从DB 1加载一个字节,但printf integer显示一个大数字



我正试图调用printf来打印一个整数,但它没有打印正确的值:

section .data
         an:    db 1
         format: db "num: %d" , 10, 0
section .text
         global main
         extern printf
main:
         push ebp
         mov ebp,esp
         mov eax, [an]
         push eax
         push dword format
         call printf
         add esp, 8
         mov esp,ebp
         pop ebp
         mov eax, 0
         ret

该代码打印"num:183641217"

当我尝试打印一个字符时,它会起作用!

section .data
         an:    db 'a'
         format: db "num: %c" , 10, 0
section .text
         global main
         extern printf
main:
         push ebp
         mov ebp,esp
         mov eax, [an]
         push eax
         push dword format
         call printf
         add esp, 8
         mov esp,ebp
         pop ebp
         mov eax, 0
         ret

现在它打印"num:a"

那么第一个代码出了什么问题?!!

db声明8位(一字节)值,而%d在x86上打印32位(四字节)值。

实际上,当用mov eax, [an]加载32位寄存器eax时,您正在将字母"num"的位加载到寄存器的高位字节。当使用%d时,它们稍后会打印为数字,而当使用%c时,它们会被忽略。

要声明32位值,应该使用dd,而不是db

@zch指出了这个问题。但是,如果你真的想把字节数据项打印成整数,并且没有重新定义它的奢侈,你可以这样做:

     movsx eax, BYTE [an]       ; [an] is a byte value to be printed with %d
     push  eax
     push  dword format
     call  printf

movsx指令符号将8位或16位操作数(在本例中为8位操作数[an])扩展到32位寄存器eax。如果它是无符号的,那么您将使用movzx eax, [an](零填充)。通常在C中,向整数的提升是隐式完成的。但在组装中,你需要自己完成。

相关内容

最新更新