如何解决汇编代码中某些指令的段错误?

How to solve segmentation fault of certain instructions of assembly code?

我写了一些简单的汇编代码如下:

.global _start

.text
_start:
    call _sum
    subq [=10=]x8, %rsp
    popq %rax
    ret
_sum:
    ret

为了在'popq'指令后得到%rax的值,

我使用 'as' 和 'ld' 命令组装了该代码。 然后我通过在'_start'

处放置断点来启动 gdb 调试器

结果如下:

B+> │0x400078 <_start>       callq  0x400083 <_sum>                            
│   │0x40007d <_start+5>     sub    [=11=]x8,%rsp                                  
│   │0x400081 <_start+9>     pop    %rax                                       
│   │0x400082 <_start+10>    retq                                              
│   │0x400083 <_sum>         retq 

但是,在进入 pop 指令之前, 出现一条错误消息说

程序接收到信号 SIGSEGV,分段错误。 无法访问地址 0x1

处的内存

(当我把$0x8改成$0x0~$0x7时,一切正常。)

似乎在第一阶段求和函数可能是问题所在。因为它实际上只做 return.

那么,如何修改此代码以在 popq 指令之后获取 %rax 的值?

谢谢。

我想这个问题可能是重复的,但无论如何,你的代码中有一个问题。

.global _start

.text
_start:
    call _sum
    subq [=10=]x8, %rsp
    popq %rax
    ret # <-- return to where?
_sum:
    ret

C 中的main必须可以return因为_start最终会调用main,但是在这里,你是直接写_start。如果你放一个 ret.

它 return 到不了任何地方

用这个代替 ret

movl , %eax # syscall number for sys_exit
movl [=11=], %edi # or whatever value you want your process
             # to return with from 0 to 255;
             # xor %edi, %edi is usually better if you want 0
syscall

如果仍然崩溃,请发表评论。


顺便说一句,我假设您的平台是 Linux(因为 AT&T 语法......)。不同平台的系统调用可能不同。