3

I try to print an integer using printf in x86 assembly. For the format string printf(fmtstring, vals) i have stored the %d as fmtd. Then i put 1 into ax, 2 into bx, add them and want to print the result using call printf. Here is the code.

global _main

extern _printf

section .data
    fmtd db "%d"

section .text

_main:
    push ebp
    mov ebp, esp

_begin:
    mov ax, 1
    mov bx, 2
    add ax, bx
    push ax
    push fmtd
    call _printf
    add esp, 8

_end:
    mov esp, ebp
    pop ebp
    ret

but i get

-10485757

instead of expected

3

can you help me whats wrong with it?

When i just write

push 3
push fmtd
call _printf

it works as usual and prints 3.

Thank you

  • 2
    If you're doing 32 bit, shouldn't that be `mov eax,1`, `mov ebx,2`, etc? – lurker Feb 12 '19 at 12:33
  • Cant i just put a 1 into 16 bit so that it looks like `00000000 00000001` with the one on the right outer side? Is it in my case `10000000 00000000` or `10000000 20000000`? –  Feb 12 '19 at 12:37
  • ...and don't forget `push eax` instead of `push ax`. – Jabberwocky Feb 12 '19 at 12:38
  • 1
    Not clear what you're asking in your comment. In your code, you're trying to print 3 from the registers. You `push ax` which pushes 16 bit register (2 bytes) then `push fmtd` which pushes a 4 byte address. You need to push a 4 byte value for the `%d`, which would be `push eax`. To be clear on the whole sequence: `mov eax,1`, `mov ebx,2`, `add eax, ebx`, `push eax` then call `printf`. – lurker Feb 12 '19 at 12:40
  • `-10485757` is `FF600003` in hexadecimal. Does that ring a bell? – Jabberwocky Feb 12 '19 at 12:43
  • When i `mov ax 1 mov bx 2` is it the same as when i `mov eax 12`? –  Feb 12 '19 at 12:43
  • sorry i changed store to mov, it was a mistake –  Feb 12 '19 at 12:44
  • @Rajana of course not, what makes you think it's the same? `eax` is not related to `bx` at all, you should read your documentation again. BTW that's another question. Please ask one question at a time. – Jabberwocky Feb 12 '19 at 12:45
  • Read this: https://stackoverflow.com/questions/15191178/how-do-ax-ah-al-map-onto-eax. Google is your friend – Jabberwocky Feb 12 '19 at 12:46
  • @Rajana, `mov ax, 1` and `mov bx 2` is not at all the same as `mov eax, 12`. `bx` is not connected to `ax` or `eax`. They are completely separate registers. – lurker Feb 12 '19 at 12:48
  • I was about to say how does this not crash after you push 6 bytes and the `add esp,8`, but your stack-frame cleanup saved you with `mov esp,ebp`. Although note that the low 2 bytes of your return address was below ESP for a couple instructions, and thus your code was at least theoretically unsafe. – Peter Cordes Feb 12 '19 at 13:54

1 Answers1

2

You need to use the full 32 bit registers:

You want this:

mov eax, 1
mov ebx, 2
add eax, ebx
push eax
push fmtd
call _printf

Explanation of output -10485757 you get:

-10485757 in hexadecimal is FF600003. The 0003 comes from the push ax which pushes the 16 low bits of eax. The FF60 is whatever leftover was on the stack.

Reads this SO article for detailed explanation about the relationship between ax and eax.

Jabberwocky
  • 40,411
  • 16
  • 50
  • 92