首页 文章

有人能解释一下这段代码吗?

提问于
浏览
-2

英语这不是我的第一语言,所以如果我拼错了一些话对不起 . 我在堆栈方面遇到了一些麻烦,我将放在这里的所有代码都能完美运行 .

这个代码例如它很容易,我理解它的堆栈 .

.globl f 
    f:

    push %ebx
    movl 8(%esp), %eax
    movl 12(%esp), %ebx

    addl %ebx, %eax

    ret

-------
    VAR Y --> ESP + 12
    -------
    VAR X --> ESP + 8
    -------
    RET   --> RETURN
    -------
    %EBX  --> %ESP
    -------

但是这个代码我已经有了一些

.code32

    .globl f

    f:

        pushl %ebx

        movl 8(%esp), %ebx

        subl $8, %esp # Creo posto nella stack per i parametri

        movl $1, (%esp)

        movl $2, 4(%esp)

        call a

        addl %ebx, %eax

        addl $8, %esp #Tolgo posto nella stack

        popl %ebx

        ret

代码工作得很好,但我对此有很多疑问?现在%ebx和堆栈在哪里?

在c中转换的asm代码:

int f(int x){

    return x + g(y,z);

    }

这就是我所做的堆栈

--------
    8(%esp) --> x parameter of function f
    --------
    4(%esp) --> z parameter of function g
    --------
    (%esp)  -->  y parameter of funcion g
    --------

所以现在的问题是%ebx在哪里,现在退回到这个堆栈?

1 回答

  • 0

    第一个代码将返回旧的 ebx 值(可能不是有效地址),而不是原始返回地址,它在 ret 之前缺少 pop ebx .

    在第二次调用 ss:esp 指令之前 ss:esp 地址的内存包含:

    dword 1                     +0 (current esp)
    dword 2                     +4
    dword old_ebx_value         +8
    dword return_address_from_f +12
    dword x                     +16
    ... older stack content ...
    

    你的"esp+x"符号不起作用,因为esp确实动态改变,所以如果你想描述那样的堆栈,你必须说明你在使用的代码中的哪个位置(esp的值) . IE浏览器 . 在 f 的条目 mov eax,[esp+4] 将加载"x",但是在 push ebx 之后只有一条指令同样的事情是通过 mov eax,[esp+8] 实现的(英特尔语法,自己转换为"machine" gas / at&t语法,我是人类) .

    但即使这样,如果你将它描述为内存值,它会随着每个 push 动态地改变或写入内存,所以你仍然必须指定你在描述堆栈的执行点(就像我在 call a 之前所做的那样,因为在 call a 之后,在该值 1 之前写入了指令 addl %ebx, %eax 的地址,并且 a 处的代码没有显示出来 .

    无论如何旧的 ebx 和返回地址始终在同一个地方的内存中(除非 a 覆盖它们),它's not the content that moves. It'是由 push/pop/add/sub 调整的指针 esp . (即使在你自己的堆栈之后,内存内容也将保留一段未定义的时间,因此这些值可能会保留在那里,直到你用下一个 pushcall 或其他方式覆盖它们) .

    最后,只需编译这些东西,然后在调试器中运行它们,在开始时将内存视图放到 ss:esp-32 ,并观察如何通过 callpush 等指令写入内存,以及 esp 如何更改为指向"top of stack" . 调试器中的"watch it"通常比阅读文本更容易 .

相关问题