Reputation: 876
Hi I am working on a factorial program for an assignment. I am receiving a segmentation fault and I am not sure why.
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
a loop to go through all variables of the nums vector
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
to print the average
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
just printing a new line
ptln:
mov eax,4
mov ebx,1
mov ecx,nln
mov edx,1
int 0x80
ret
exit command
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
I know the problem starts at the $mov esp,[nums+esi]$ line but I don't know what is wrong. I added the full code because I don't really understand what I am doing.
Upvotes: 0
Views: 66
Reputation: 876
The call
and ret
instructions (and probably int
) implicitly use the stack, and therefore require esp
to point to the correct location (i.e. the current top of the current thread's stack; or the current top of some stack that you've set up yourself). Since you're using esp
as a general-purpose register in your code you end up accessing memory locations that your application most likely doesn't have access to as soon as you execute e.g. a 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
Rule of thumb: Do not use esp
as a general-purpose register unless you're really, really sure that it's ok to do so.
Another potential problem is that nums
is accessed as if it was an array of doubleword, even though it's declared as an array of bytes.
Upvotes: 1