Assembly 更改地址在堆栈中的变量
假设这是我的主要任务Assembly 更改地址在堆栈中的变量,assembly,x86,masm,irvine32,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
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
但这对你的尝试不起作用
mov OFFSET[ebp+8], 10
间接或索引操作数对于OFFSET
运算符无效,我认为您误解了OFFSET
的返回值,它是一个立即操作数,“数据的有效地址”,另外,OFFSET
运算符的返回值会使MOV
指令的目标操作数成为无效的立即操作数
在您的情况下,如果堆栈上已存在variableName
的偏移量,请首先在临时寄存器中加载该偏移量,并仅使用间接操作数解引用,但必须使用PTR
运算符指定大小
mov esi,[ebp+8]
mov DWORD PTR[esi],10
关于你的尝试
mov OFFSET[ebp+8], 10
间接或索引操作数对于OFFSET
运算符无效,我认为您误解了OFFSET
的返回值,它是一个立即操作数,“数据的有效地址”,另外,OFFSET
运算符的返回值会使MOV
指令的目标操作数成为无效的立即操作数
在您的情况下,如果堆栈上已存在variableName
的偏移量,请首先在临时寄存器中加载该偏移量,并仅使用间接操作数解引用,但必须使用PTR
运算符指定大小
mov esi,[ebp+8]
mov DWORD PTR[esi],10
您正在按指针,如注释中所述,您需要遵守它。
请参阅此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
对应的内容。这可能有助于您理解差异 您正在按一个指针,正如您需要遵守的注释中所述。
请参阅此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
对应的内容。这可能有助于您理解差异 你需要再次取消引用。将地址加载到暂存寄存器中,然后取消引用。您需要另一次取消引用。将地址加载到一个临时寄存器中,然后删除它。哈哈!没问题。我以前遇到过“Ooops我一直在测试错误的程序”的情况;-)。我现在就删除我以前的评论哈哈!没问题。我以前遇到过“Ooops我一直在测试错误的程序”的情况;-)。我现在将删除我以前的评论