Question

I compile code

gcc -g3 hello3.s -o hello

.data

ssttrr:
  .string "%d\n"

.text
.globl main

main:

  mov $213, %rdx
  push %rdx
  push $ssttrr
  call printf
  add  $8, %rsp

mov  $60, %rax
xor  %rdi, %rdi
syscall

I understand error but i don't know how fix it. I even don't know when error is. cpy: intel-64 os: debian

Was it helpful?

Solution

The default calling convention for x86_64 has changed and it now not only uses stack, but also uses registers to pass parameters:

Passing

Once arguments are classified, the registers get assigned (in left-to-right order) for passing as follows:

  1. If the class is MEMORY, pass the argument on the stack.
  2. If the class is INTEGER, the next available register of the sequence %rdi, %rsi, %rdx, %rcx, %r8 and %r9 is used*
  3. If the class is SSE, the next available SSE register is used, the registers are taken in the order from %xmm0 to %xmm7.

...

*Note that %r11 is neither required to be preserved, nor is it used to pass arguments. Making this register available as scratch register means that code in the PLT need not spill any registers when computing the address to which control needs to be transferred. %raxis used to indicate the number of SSE arguments passed to a function requiring a variable number of arguments. %r10 is used for passing a function’s static chain pointer.

You would want to pass in the string and the integer value in %rdi and %rsi registers respectively, instead of pushing them directly unto the stack:

mov $213, %esi ;%d is not a 64-bit integer
mov $ssttrr, %rdi
mov $0, %rax ;no sse registers as arguments
call printf
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top