4

我正在阅读一些 linux 汇编手册,并找到了有关使用 printf() 函数的想法。我需要它以二进制形式将寄存器值以二进制形式输出到终端,但现在我只是尝试用文本测试该函数。

我被卡住了,因为当我使用 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
4

1 回答 1

10

Linux(和 Windows)x86-64 调用约定的前几个参数不在堆栈中,而是在寄存器中

请参阅http://www.x86-64.org/documentation/abi.pdf(第 20 页)

具体来说:

  1. 如果类是 MEMORY,则在堆栈上传递参数。
  2. 如果类是 INTEGER,则使用序列 %rdi、%rsi、%rdx、%rcx、%r8 和 %r9 的下一个可用寄存器。
  3. 如果类是 SSE,则使用下一个可用向量寄存器,寄存器按从 %xmm0 到 %xmm7 的顺序获取。
  4. 如果类是 SSEUP,则在最后使用的向量寄存器的下一个可用的八字节块中传递八字节。
  5. 如果类是 X87、X87UP 或 COMPLEX_X87,则在内存中传递。

该类INTEGER是适合通用寄存器的任何内容,因此您也可以将其用于字符串指针。

于 2012-06-01T21:03:58.063 回答