2013-09-26 115 views
1

我在裝配一個小程序時遇到了一點麻煩。它應該只打印堆棧中的所有內容,然後退出。據我所知,程序啓動後,堆棧上有很多東西。它確實打印了很多東西,但是隨後出現了分段錯誤。裝配,彈出堆棧到極限

下面是代碼:

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 

正如你可以看到條件退出循環是ESP == EBP這在我的理解應該是這樣的,當堆棧爲空。不幸的是,當用gdp檢查程序時,看起來ebp的值爲0.不是ebp應該指向堆棧底部,即具有最高地址嗎?

我真的很感激任何提示。

設置:Linux操作系統,32位,NASM

問候

+3

堆棧指針是當你的程序被稱爲系統建立,但你需要設置'ebp'你需要的方式。不能保證在開始時等於堆棧指針,或者相對於堆棧指針有一些特定的值。有關參考資料,請參閱:http://en.wikibooks.org/wiki/X86_Disassembly/Functions_and_Stack_Frames – lurker

回答

1

堆棧指針是由系統建立你的程序被調用時,但你需要設置ebp你需要的方式。不能保證在開始時等於堆棧指針,或者相對於堆棧指針有一些特定的值。作爲參考,請參閱:x86 function stack frames

就你而言,你似乎假設一些參數已經被推入堆棧,並且你想在用完這些參數後退出。要麼你的代碼需要知道有多少,要麼第一個參數需要是有多少的計數,你可以使用這個計數。在任何一種情況下,您都可以將計數值存入計數寄存器(ecx,如果您想使用loop指令,則很方便)並根據計數值進行循環。另外,從你的代碼中,我假設參數是數據的地址(指針)。例如:

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 
0

在Linux EBP是絕對不會被初始化到堆棧的結束!

事實上,沒有簡單的可能性來獲得堆棧的結束。

程序中還有一個錯誤:ECX必須包含要寫入的數據的地址 - 而不是數據本身!

也許你可以做這樣的:

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