I'm having a little trouble with a little assembly program. It is supposed to just print everything what is on the stack and then exit. As far as I know there is quite some stuff on the stack after the program started. It does actually print a lot of stuff but exits then with a segmentation fault.
Here is the code:
SECTION .data
SECTION .bss
SECTION .text
global _start
_start:
mov eax,4
mov ebx,1
pop ecx
mov edx,4
int 80h
cmp esp,ebp
je out
jmp _start
out:
mov eax,1
mov ebx,0
int 80h
As you can see the condition for quitting the loop is esp==ebp which in my understanding should be the case when the stack is empty. Unfortunately when inspecting the program with gdp it appears that ebp has a value of 0. Isn't ebp supposed to point on the bottom of the stack ie have the highest address?
I would really appreciate any hints.
Setup: linux, 32 bit, nasm
Regards
The stack pointer is establish by the system when your program is called, but you need to set up ebp
the way you need it. It's not guaranteed to be equal to the stack pointer at the start, or some specific value relative to the stack pointer. For reference, see: x86 function stack frames .
In your case, it appears that you are assuming some parameters have been pushed on the stack, and you want to quit after you've exhausted these parameters. Either your code needs to know how many there are, or the first parameter needs to be a count of how many there are and you can use that count. In either case, you put the count into a count register ( ecx
is convenient if you want to use the loop
instruction) and loop based upon the count. Also, from your code, I'm assuming that the parameters are addresses (pointers) to the data. For example:
SECTION .data
SECTION .bss
SECTION .text
global _start
_start:
mov ebp,esp ; point to the parameters via ebp
mov ecx,[ebp] ; first parameter is the count of values
; or, for example, "mov ecx,4" if there are fixed 4 params
mov esi,1 ; Initial index to parameters
_loop:
push ecx ; save the loop counter
; Uncomment these to save ebp and esi if int 80h uses these registers
;push ebp
;push esi
mov eax,4 ; sys_write call
mov ebx,1 ; stdout
mov ecx,[ebp+4*esi] ; get the next pointer
mov edx,4 ; print 4 characters
int 80h
; Uncomment these to restore esi and ebp if int 80h uses these registers
;pop esi
;push ebp
inc esi ; next parameter index
pop ecx ; restore the loop counter
loop _loop
mov eax,1
mov ebx,0
int 80h
Under Linux EBP is definitely not initialized to the end of the stack!
In fact, there is no simple possibility to get the end of the stack.
There is another bug in your program: ECX must contain the address of the data to be written - not the data itself!
Maybe you could do it like this:
global _start
_start:
mov ecx,esp
_loop:
mov eax,4
mov ebx,1
mov edx,4
int 80h
add ecx,4
test eax,eax
jns _loop
mov eax,1
mov ebx,0
int 80h
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.