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

问候

4

2 回答 2

1

当你的程序被调用时,堆栈指针是由系统建立的,但你需要设置ebp你需要的方式。它不保证等于开始时的堆栈指针,或者相对于堆栈指针的某个特定值。有关参考,请参阅:x86 函数堆栈帧

在您的情况下,您似乎假设一些参数已被压入堆栈,并且您想在用完这些参数后退出。您的代码需要知道有多少,或者第一个参数需要是有多少的计数,您可以使用该计数。在任何一种情况下,您都将计数放入计数寄存器(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
于 2013-09-26T20:51:35.233 回答
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
于 2013-09-26T19:35:02.713 回答