在x86中调用printf来打印整数

时间:2015-03-19 10:57:25

标签: assembly x86 printf call nasm

我正在尝试调用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:1836412417”

当我尝试打印它的作品时,它会起作用!

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”

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

2 个答案:

答案 0 :(得分:6)

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

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

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

答案 1 :(得分:5)

@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中,提升为整数是隐式完成的。但是在集会中,你需要自己做。