所以假设这是我的主要
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
但不起作用
您正在推动一个指针,正如注释中所指出的,您需要尊重它。
请参阅Godbolt示例,其中的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
请特别注意C代码foo
和bar
对应的内容。
这可能有助于您理解差异。
关于您的尝试,
mov OFFSET[ebp+8], 10
间接或索引操作数对OFFSET
运算符无效,我认为您误解了OFFSET
的返回值,即立即数操作数"数据的有效地址",而且OFFSET
运算符的返回值会使MOV
指令的目标操作数成为无效的立即数操作。
在您的情况下,如果堆栈上已经有variableName
的偏移量,请先将偏移量加载到临时寄存器中,然后只使用间接操作数解引用,但必须使用PTR
运算符指定大小。
mov esi,[ebp+8]
mov DWORD PTR[esi],10