Почему я получаю ошибку сегментации?

я компилирую код

gcc -g3 привет3.s -о привет

.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

Я понимаю ошибку, но я не знаю, как это исправить. Я даже не знаю, когда ошибка. копия: intel-64 ОС: debian


person volkov    schedule 15.04.2013    source источник
comment
Является ли это допустимым соглашением о вызовах для функций C? Добавляет ли .string нулевой байт в конец строки?   -  person Alexey Frunze    schedule 15.04.2013
comment
Ты хоть представляешь, что означает calling convention?   -  person Alexey Frunze    schedule 15.04.2013
comment
Будет ли работать это?   -  person Alexey Frunze    schedule 15.04.2013
comment
Связано: Вызов printf в x86_64 с использованием ассемблера GNU   -  person Peter Cordes    schedule 11.06.2018


Ответы (1)


Соглашение о вызовах по умолчанию для x86_64 изменилось, и теперь оно использует не только стек, но и регистры для передачи параметров:

Прохождение

Как только аргументы классифицированы, регистры назначаются (в порядке слева направо) для передачи следующим образом:

  1. Если класс MEMORY, передайте аргумент в стеке.
  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.

...

*Обратите внимание, что %r11 не требуется сохранять и он не используется для передачи аргументов. Предоставление этого регистра в качестве вспомогательного регистра означает, что коду в PLT не нужно сбрасывать какие-либо регистры при вычислении адреса, на который необходимо передать управление. %raxis используется для указания количества аргументов SSE, переданных функции, требующей переменного количества аргументов. %r10 используется для передачи указателя статической цепочки функции.

Вы хотели бы передать строку и целочисленное значение в регистры %rdi и %rsi соответственно, вместо того, чтобы помещать их непосредственно в стек:

mov $213, %esi ;%d is not a 64-bit integer
mov $ssttrr, %rdi
mov $0, %rax ;no sse registers as arguments
call printf
person JosephH    schedule 15.04.2013