assembly 汇编程序,将整数作为十六进制输出到标准输出

bpzcxfmw  于 2023-01-21  发布在  其他
关注(0)|答案(1)|浏览(128)

我必须为x86处理器编写一个nasm(或其他)汇编程序,在标准输出上打印32位十六进制数,例如printf(“%x\n”,123456),并使用write系统调用来显示。我写了一些代码,但似乎不起作用。comeone能帮我吗?

section .data
    message db '0x',0
    number dq 123456

section .text
    global _start

_start:
    ; Print "0x"
    mov eax, 4
    mov ebx, 1
    mov ecx, message
    mov edx, 2
    int 0x80

    ; Print number in hex
    mov eax, number
    push eax
    call print_hex
    add esp, 4

    ; Exit
    mov eax, 1
    xor ebx, ebx
    int 0x80

; Function to print number in hex
print_hex:
    push ebx
    push edx
    mov ebx, 16
    mov edx, 0
    mov ecx, 0

print_hex_loop:
    xor edx, edx
    div ebx
    add edx, '0'
    cmp edx, '9'
    jg print_hex_digit
    push edx
    inc ecx
    test eax, eax
    jne print_hex_loop

print_hex_done:
    mov eax, 4
    mov ebx, 1
    mov edx, ecx
    int 0x80

print_hex_pop_loop:
    pop edx
    mov [esp], edx
    inc esp
    dec ecx
    jne print_hex_pop_loop
    pop edx
    pop ebx
    ret

print_hex_digit:
    add edx, 'A' - '9' - 1
    jmp print_hex_done

我是汇编程序新手,所以我不知道如何让它正常工作

5tmbdcev

5tmbdcev1#

我假设该函数接受一个如下所示的无符号32位数

void printhex( uint32_t number );

这里的想法是保留32位整数的最大长度(16个字符加上末尾的空字符),然后开始向后填充十六进制数。
一旦数字变为零,我们就打印并返回。

/************ print 32-bit hexadecimal number ***********/
.globl  printhex
printhex:
        // On entry EDI contains number to be printed
        // We will print from the back to the front
        subq    $24, %rsp      // Reserve stack (multiple of 8)
        movb    $0, 18(%rsp)   // Set a null \0 at the end
        leaq    18(%rsp), %rax // ptr = pointer to that null
loop:
        movl    %edi, %esi     // Save number to ESI
        decq    %rax           // Decrement pointer
        movl    %edi, %edx     // Store number into EDX
        shrl    $4, %edi       // number = number / 16
        andl    $15, %edx      // digit = number % 16
        leal    87(%rdx), %ecx // hexdigit = digit + ('a'-10)
        cmpl    $9, %edx      // is digit > 10?
        ja      greater10
        leal    48(%rdx), %ecx // hexdigit = digit + '0'
greater10:
        movb    %cl, (%rax)    // *ptr = hexdigit
        cmpl    $15, %esi      // (saved) number > 15?
        ja      loop           // yes, loop back
                               // no, print and finish
        movb    $120,-1(%rax)  // store '0x'
        movb    $48,-2(%rax)
        leaq    -2(%rax), %rdi // 1st arg to puts = ptr
        call    puts           // print
        addq    $24, %rsp      // Restore stack
        ret                    // Return

呼叫者可以是

.globl _start
_start:
        movl    $0x12abcdef, %edi  // 4660 = 0x1234
        call    printhex
        movq    $60, %rax    // Finish with syscall
        movl    $0,%edi
        syscall

运行它会产生

$ gcc printhex.S -o printhex -nostartfiles
$ ./printhex
0x12abcdef

相关问题