【问题标题】:Assembly, popping the stack to the limit组装,将堆栈弹出到极限
【发布时间】:2013-10-02 18:01:30
【问题描述】:

我在使用一个小汇编程序时遇到了一点麻烦。它应该只打印堆栈上的所有内容,然后退出。据我所知,程序启动后堆栈上有很多东西。它确实打印了很多东西,但随后退出并出现分段错误。

代码如下:

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

问候

【问题讨论】:

  • 堆栈指针是系统在调用你的程序时建立的,但是你需要按照你需要的方式设置ebp。它不保证等于开始时的堆栈指针,或者相对于堆栈指针的某个特定值。参考见:en.wikibooks.org/wiki/X86_Disassembly/…

标签: linux assembly x86 nasm 32-bit


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    堆栈指针是在你的程序被调用时由系统建立的,但是你需要按照你需要的方式设置ebp。它不保证等于开始时的堆栈指针,或者相对于堆栈指针的某个特定值。参考请见:x86 function stack frames

    在您的情况下,您似乎假设某些参数已被压入堆栈,并且您想在用完这些参数后退出。您的代码需要知道有多少,或者第一个参数需要是有多少的计数,您可以使用该计数。无论哪种情况,您都将计数放入计数寄存器(如果您想使用loop 指令,ecx 很方便)并根据计数循环。另外,从您的代码中,我假设参数是数据的地址(指针)。例如:

    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
    

    【讨论】:

      猜你喜欢
      • 2019-08-08
      • 1970-01-01
      • 1970-01-01
      • 2017-12-26
      • 2012-10-12
      • 1970-01-01
      • 2018-05-09
      • 2014-02-14
      • 1970-01-01
      相关资源
      最近更新 更多