更改地址在堆栈中的变量

时间:2018-11-22 02:18:47

标签: assembly x86 masm irvine32

所以说这是我的主要

main PROC
    sub esp, 4
    push OFFSET variableName
    call changeVariable

changeVariable PROC
    push ebp
    mov ebp, esp

如何在changeVariable过程中将variableName更改为其他值(例如10)?

我尝试过

mov OFFSET[ebp+8], 10  ;ebp[+8] is the position in stack that holds address of variableName

但这不起作用

2 个答案:

答案 0 :(得分:2)

关于您的尝试,

mov OFFSET[ebp+8], 10

间接或索引操作数对OFFSET运算符无效,我认为您误解了OFFSET的返回值,该返回值是立即操作数,即“数据的有效地址”,也是的返回值OFFSET运算符会使MOV指令的目标操作数成为无效的立即数。

如果您的堆栈中已经有偏移量variableName,请先将偏移量加载到临时寄存器中,然后使用间接操作数取消引用,但必须使用{{1 }}运算符。

PTR

答案 1 :(得分:2)

您正在推动指针,如注释中所述,您需要遵从它。
请参考this Godbolt example,此处的C代码

void bar(int* c)
{
    *c = 10;
}

void foo(int c)
{
        c = 10;
}

int myVar;

int main()
{
    bar(&myVar);

    foo(myVar);
}

被组装成

bar:
        push    ebp
        mov     ebp, esp

        ;What you need to do:
        mov     eax, DWORD PTR [ebp+8]     ;Read the pointer
        mov     DWORD PTR [eax], 10        ;Deference it

        nop
        pop     ebp
        ret

foo:
        push    ebp
        mov     ebp, esp

        ;What you are doing:
        mov     DWORD PTR [ebp+8], 10  ;Overwriting an argument

        nop
        pop     ebp
        ret

main:
        push    ebp
        mov     ebp, esp

        ;This is you call exactly
        push    OFFSET FLAT:myVar
        call    bar
        add     esp, 4

        ;How one would call the foo version
        mov     eax, DWORD PTR myVar
        push    eax
        call    foo
        add     esp, 4


        mov     eax, 0
        leave
        ret

要特别注意foobar对应的C代码。
这可以帮助您了解差异。