装配,分段故障

时间:2015-08-07 22:40:54

标签: assembly x86

此代码导致分段错误,我不知道为什么会这样做, 该代码只是将堆栈中esp的当前位置传递给ebp 并在ebp上使用间接寻址模式来获取地址的值, 我不知道操作系统为什么会终止导致分段错误

.section .data
.section .text
.globl _start
_start:
movl $50,%edx
pushl, %edx
movl %esp,%ebp
movl (%ebp),%ebx  ## this causes the problem for some reason, 
movl $1,%eax     
int $0x80         ## Program should return an exit status of %ebx value

1 个答案:

答案 0 :(得分:0)

正如Jester所说,问题是64位Linux工具默认制作64位程序。他习惯在评论中写下他的答案,所以我在这里复制一下:

as --32 test.s -o test.o; ld -melf_i386 test.o -o test

gcc -m32 foo.s -ffreestanding -nostdlib -o foo

movl (%ebp),%ebx

因为%rsp在高32位中不是全零,所以%esp是与%rsp不同的地址。你可以用gdb找到这个问题。你已经注意到你有64位寄存器。有关使用gdb for asm的信息,请参阅https://stackoverflow.com/tags/x86/info

我将更多地选择这一行:

pushl, %edx

除了语法错误(额外的逗号)之外,_start不需要保存任何寄存器。 x86-64 ABI says你应该假设它们都是随机垃圾,除了堆栈指针。它还说%rdx具有您应该向atexit()注册的函数的地址,但在当前的Linux上,%rdx在进程条目上归零。 (命令行参数位于堆栈中。)

我认为x86 32位进程启动的情况基本相同。