Question

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 i.e. have the highest address?

I would really appreciate any hints.

Setup: linux, 32 bit, nasm

Regards

Était-ce utile?

La solution

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

Autres conseils

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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top