您好我正在为一项作业制定一个因子计划。我收到了分段错误,我不确定原因。
section .data ;constants
nums: db 13,21,14,25,34,63,23,23,42,0x32 ;numbers sum = 290 ave 29
len: db $-nums
nln: db 0xA
msg: db "Average",0xA
mlen: db $-msg
section .bss ;variables
spot: resb 1
total: resb 4
ave: resb 4
ob1: resb 1
ob2: resb 1
ob3: resb 1
section .text ;code
global _start
_start:
sub esi,esi
mov byte [total],0
循环遍历nums矢量的所有变量
loop:
mov esp,[nums+esi]
call ptln
call convert_ascii
call print_conv
add [total],esp
mov ecx,total
add esi,1
cmp esi,10
jmp ptave
jmp loop
打印平均值
ptave:
mov esp,[total]
mov eax,4
mov ebx,1
mov ecx,msg
mov edx,mlen
int 0x80
call convert_ascii
call print_conv
jmp exit
只是打印一个新行
ptln:
mov eax,4
mov ebx,1
mov ecx,nln
mov edx,1
int 0x80
ret
退出命令
exit:
mov ebx,0
mov eax,1
int 0x80
convert_ascii:
mov byte [ob1],0
mov byte [ob2],0
mov byte [ob3],0
xor edx,edx
mov eax,10
div esp
mov [ob3],edx
div esp
mov [ob2],edx
div esp
mov [ob1],edx
ret
print_conv:
mov eax,4
mov ebx,1
mov ecx,ob1
mov edx,1
int 0x80
mov ecx,ob2
int 0x80
mov ecx,ob3
int 0x80
我知道问题始于$ mov esp,[nums + esi] $ line但我不知道出了什么问题。我添加了完整的代码,因为我不太了解我在做什么。
答案 0 :(得分:1)
call
和ret
指令(可能int
)隐式使用堆栈,因此需要esp
指向正确的位置(即当前顶部当前线程的堆栈;或者您自己设置的某些堆栈的当前顶部)。由于您在代码中使用esp
作为通用寄存器,因此您最终会访问您的应用程序在您执行时很可能无法访问的内存位置。 call
:
mov esp,[nums+esi]
call ptln ; call tries to push the return address onto the stack, but esp
; now contains one of the values from nums: OOPS! -> segfault
经验法则:不使用esp
作为通用寄存器,除非您真的,确实确定它是'可以这样做。
另一个潜在的问题是访问nums
就好像它是一个双字数组,即使它被声明为一个字节数组。