我正在学习装配,我刚刚阅读了本书中关于功能的章节。
在这里,我想尝试一些基于条件的简单函数调用:
如果val1 == val2,则调用func2,否则调用func1。
但是在执行程序时我得到segmentation fault
。我看不出问题出在哪里。
.section .data
val1: .int 25
val2: .int 50
ans1: .int 100
ans2: .int 200
.section .text
.globl _start
_start:
movl val2, %ecx # put val2 to %ecx
cmpl val1, %ecx # compare val1 and %ecx (val2)
je call_func2 # if val1 == val2, jump to call_func2
call_func1: # else execute call_func1
call func1
jmp endifblock
call_func2:
call func2 # call func2
jmp endifblock
endifblock:
nop
popl %edx # pop result from stack into %edx
movl $1, %eax
movl %edx, %ebx # set result (%edx) as exit code
int $0x80
.type func1, @function # function "func1"
func1:
pushl ans1 # push ans1 to stack (it seems this causes the segmentation fault)
ret
.type func2, @function # function "func2"
func2:
pushl ans2 # push ans2 to stack (it seems this causes the segmentation fault)
ret
答案 0 :(得分:1)
分段错误意味着您尝试访问的其中一个地址(数据或指令)不属于此程序。
没有详细阅读,但有一个显而易见的问题:我在功能结束时没有看到“返回”......
答案 1 :(得分:1)
问题在于:
func1:
pushl ans1
ret
函数中的“答案”不能在堆栈中。如果将值推送到堆栈,ret
指令将把该值作为跳转到的地址,从而导致段错误。
您必须选择一个寄存器来保存返回值(通常是IA32架构中的EAX)并执行以下操作:
func1:
mov ans1, %eax
ret
(func2
当然有同样的问题)
您的应用程序在调用func1
或func2
后,将返回该值,从EAX
读取,而不是从堆栈中读取:
movl %eax, %edx # save value returned from function into EDX
movl $1, %eax
movl %edx, %ebx # set result (%edx) as exit code
int $0x80