1

I want to add the number 0xFFFFFFFF with himself and then print the result to screen. For this, I'm using the memory location result to hold the results (that may be up to 64bit). In order to call printf, I need to push it to stack but this: push qword [result] not compiled. there is any way to send the 64 bit number to printf?

section .data
fmt1: dq "%x", 10, 0
result: dd 0,0

section .text
    extern printf  

assFunc:

mov edx,0
mov eax, 0xFFFFFFFF
add eax, 0xFFFFFFFF
adc edx,0


mov [result],edx
mov [result+4],eax

push [result]
push fmt1
call printf
add esp,8 
Jester
  • 56,577
  • 4
  • 81
  • 125
go vegan
  • 31
  • 3
  • 1
    You will need to do it in two halves. `push dword [result+4]; push dword [result]`. Note that `%x` does not take a 64 bit number. Also your `fmt1` should be `db` not `dq` (although it is probably harmless). – Jester Apr 26 '20 at 17:18
  • 2
    You should store the low half of the value in `[result]` and the high half in `[result+4]` to match the way all multibyte values are stored on x86. Note that the comment by @Jester was written with the assumption that it is stored this way. – prl Apr 26 '20 at 17:23
  • @prl good catch! – Jester Apr 26 '20 at 17:30
  • thank u both! I changed to `push dword [result+4]; push dword [result]` but still not understand how to print the decimal value correctly. this `fmt1: db "%d%d", 10, 0` not working – go vegan Apr 26 '20 at 17:34
  • 2
    Use `%lld` (once). – Jester Apr 26 '20 at 17:38
  • @Jester thanks. this is working but one of the assignment requirement is to user only %d ("prints result in decimal base, using printf with '%d' format"). can I do it with my approach? – go vegan Apr 26 '20 at 19:25
  • If you can only use `%d` but you are allowed multiple calls it might actually be simplest to do a conversion to decimal yourself and print the digits one by one. – Jester Apr 26 '20 at 21:53

1 Answers1

3

There are a few mistakes in your code.

The fmt string is defined with dq which defines groups of QWORDs (64-bit items). This has the effect of padding (with zero bytes) every string to multiple of 8 bytes.
In this case, you would lose the new line char.
Use db instead.

It's also better to follow the little endian convention and store the high part of a number in the higher addresses.
edx is the high part of the result, store it in [result + 4] and store eax (the lower part) in [result].
This makes it easy for other programmers to reason about your code. By the same length, you can also use xor edx, edx to set edx to zero.

Finally, the printing part.
First of all, the correct format string is %llx since the model used by the mainstream compilers in 32-bit mode is LL64 (i.e. long is still 32 bits, while long long is 64 bits).

The ABI says you have to pass long long arguments on the stack and that their alignment is 4 bytes (which means, you don't have to add any padding).
Furthermore, the ABI mandates that the stack to be aligned on 16 bytes boundary just before the call instruction but, by sheer luck, using three pushes is what was needed to keep it aligned anyway. Since x86 are little endian machines, this can be accomplished with:

push DWORD [result+4]
push DWORD [result]
push fmt1
call printf
add esp, 10h

The whole code:

SECTION .data

  fmt1:   db "%llx", 10, 0
  result: dd 0, 0


SECTION .text

    EXTERN printf  

assFunc:

  mov edx,0
  mov eax, 0xFFFFFFFF
  add eax, 0xFFFFFFFF
  adc edx,0

  mov [result],eax
  mov [result+4],edx

  push DWORD [result+4]
  push DWORD [result]
  push fmt1
  call printf
  add esp, 0ch 

  ret

Note that you don't actually need to store the result in the result variable, you can

push edx
push eax

directly, instead of

push DWORD [result+4]
push DWORD [result]
Margaret Bloom
  • 41,768
  • 5
  • 78
  • 124
  • thank you very much! can you explain more about " In this case, you would lose the new line char."? why? – go vegan Apr 27 '20 at 11:12
  • @govegan Because by using `dq` the string "%x" is padded with 6 zero bytes. And `printf` stops at the first zero byte it founds. – Margaret Bloom Apr 27 '20 at 11:16