Linux X86-64 сборка и печать

Я читаю несколько руководств по сборке Linux и нашел представление об использовании функции printf(). Мне нужно, чтобы выводить значения регистров для аргументов в двоичной форме на терминал, но теперь я попробовал просто протестировать эту функцию с текстом.

Я застрял из-за segfault, когда я использую pushq вместо pushl. Как я могу изменить эту программу для вывода строк и двоичной формы регистров?

.data
input_prompt:
    .string "Hello, world!"

printf_format:
    .string "%5d "

printf_newline:
    .string "\n"

size:
    .long 0

.text
.globl main
main:
    pushq $input_prompt
    call  printf

    movl  $0, %eax
    ret

Он был скомпилирован GCC как:

gcc tmp.S -o tmp

Ответ 1

Linux (и Windows) соглашение о вызове x86-64 содержит первые несколько аргументов, не входящих в стек, но вместо этого вместо регистров

См. http://www.x86-64.org/documentation/abi.pdf (стр. 20)

В частности:

  • Если класс MEMORY, передайте аргумент в стеке.
  • Если класс INTEGER, используется следующий доступный регистр последовательности% rdi,% rsi,% rdx,% rcx,% r8 и% r9.
  • Если класс SSE, используется следующий доступный векторный регистр, регистры берутся в порядке от% xmm0 до% xmm7.
  • Если класс SSEUP, восьмибайт передается в следующем доступном восьмибайтовом блоке последнего использованного векторного регистра.
  • Если класс X87, X87UP или COMPLEX_X87, он передается в памяти.

Класс INTEGER - это все, что поместится в регистр общего назначения, так что вы также будете использовать для указателей на строку.