1
movl %ebx, %esi
movl $.LC1, %edi
movl $0, %eax
call printf

我使用以下 asm 代码打印EBX寄存器中的内容。当我使用

movl $1,%eax
int 0x80

echo $?我得到了正确的答案,但在第一种情况下出现了分段错误。我正在使用 GNU 汇编器和 AT&T 语法。我该如何解决这个问题?

4

2 回答 2

1

从代码来看,您可能处于 64 位模式(请确认),在这种情况下,指针的大小为 64 位。在 Linux 上依赖于位置的可执行文件movl $.LC1, %edi是安全的,并且编译器使用什么,但是为了使您的代码与位置无关并且能够处理在低 32 位之外的符号地址,您可以使用leaq .LC1(%rip), %rdi.

此外,请确保:

  • rbx你在你的功能中保留价值
  • 堆栈指针按要求对齐

此代码适用于 64 位:

.globl main
main:
    push %rbx
    movl $42, %ebx
    movl %ebx, %esi
    leaq .LC1(%rip), %rdi
    movl $0, %eax
    call printf
    xor  %eax, %eax
    pop  %rbx
    ret

.data
    .LC1: .string "%d\n"
于 2013-01-05T14:06:11.410 回答
0

编辑:正如 Jester 所指出的,此答案仅适用于 x86(32 位)asm,而提供的示例更可能适用于 x86-64。

那是因为 printf 有可变数量的参数。printf 调用不会为您恢复堆栈,您需要自己进行。

在您的示例中,您需要编写(32 位汇编):

push %ebx
push $.LC1
call printf
add $8, %esp  // 8 : 2 argument of 4 bytes
于 2013-01-05T06:49:11.777 回答