Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loading a byte from a DB 1, but printf integer show a large number

I'm trying to call printf to print an integer, put it doesn't print the right value:

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

this code prints "num: 1836412417"

put when I try to print a char it works!

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

now it prints "num: a"

so what's wrong with the first code ?!!

like image 945
3la210 Avatar asked Mar 19 '15 10:03

3la210


2 Answers

db declares 8-bit (one byte) values, while %d prints 32-bit (four byte) values on x86.

In effect, when loading 32-bit register eax with mov eax, [an] you are loading bits of letters "num" to high bytes of the register. They are later printed as number, when using %d or ignored when using %c.

To declare 32 bit values you should use dd, instead of db.

like image 189
zch Avatar answered Nov 11 '22 14:11

zch


@zch pointed out the issue. But if you really do want to print out a byte data item as an integer and don't have the luxury of redefining it, you can do it this way:

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

The movsx instruction sign extends an 8-bit or 16-bit operand (in this case, the 8-bit operand, [an]) into the 32-bit register, eax. If it is unsigned, then you'd use movzx eax, [an] (zero fill). Normally in C, the promotion to integer is done implicitly. But in assembly, you need to do that yourself.

like image 25
lurker Avatar answered Nov 11 '22 12:11

lurker