MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] 把寄存器ESI的值复制到ESI,复制字节为BYTE。
MOVS WORD PTR ES:[EDI],WORD PTR DS:[ESI] 把寄存器ESI的值赋值到ESI,复制字节为WORD。
MOVS DWORD PTR ES:[EDI],WORD PTR DS:[ESI] 把寄存器ESI的值复制到ESI,复制字节为DWORD。
PUSH EAX 把寄存器EAX的值赋值到当前执行的堆栈,并且ESP也就是当前执行到的堆栈的内存编号减4,具体看你执行PUSH的宽度是1字节还是2字节还是4字节。
POP EDI 恰好和PUSH相反,是把当前堆栈的值存放到EDI,并且ESP也就是当前执行到的堆栈位置,加4,具体看执行的POP的宽度是1字节还是2字节还是4字节。
重点:堆栈是内存地址从大到小。
CALL 105833C 此时会发生的变化,EIP的值也就是下一次CPU会处理的值,会变成105833C,并且堆栈也会发生变化,堆栈会开辟下一块堆栈内存,用来存储我刚刚执行CALL指令的下一个指令编号,也就是1058341。+
RET 把当前ESP也就是当前执行到的堆栈的值,赋值到EPI,并且让ESP加4,也就是后退了。
STOS指令
把AL/AX/EAX的值存储到[EDI]指定的内存单元
STOS BYTE PTR ES:[EDI] 如果是BYTE那就是AL的值存到EDI
STOS WORD PTR ES:[EDI] 如果是WORD那就是AX的值存到EDI
STOS DWORD PTR ES:[EDI] 如果是DWORD那就是EAX的值存到EDI
REP 指令
MOV ECX 00000010
REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
REP是要跟ECX搭配使用的,因为REP的作用是重复执行,那重复多少次呢?那就看ECX里的值是多少,我上面MOV ECX,10其实是16次,因为10的16进制是16.
那上面的意思就显而易见了
CALL和RET可以做加减法:
首先声明函数:
15FF110 ADD ECX,EDX #ECX+EDX结果返回给ECX
MOV EAX,ECX #因为在汇编里,结果值通常会放到EAX,所以这里也效仿。
RET #把CALL的下一行放进EIP也就是下一次执行的地方,我们调用的时候也是用CALL,所以其实就是执行完函数调用后从函数调用的下一行继续往下执行。
调用函数的部分
MOV ECX,1
MOV EDX,5
CALL 15FF110
搞定。
利用堆栈算5位数的加法:
思路是这样,首先你调用函数的时候用push往堆栈里面压值:
push 1
push 2
push 3
push 4
push 5
这里再CALL去调用函数,那函数怎么写呢?
首先把第一个值放到EAX
mov eax,dword ptr ds:[esp]也就是把当前的堆栈的值放进来,如果你push的顺序是1 2 3 4 5那么当前的位置是在5所在的堆栈。
然后往下加,越往下越大,因为是从大到小吗堆栈的地址。
add eax,dword ptr ds:[esp+4]
add eax,dword ptr ds:[esp+8]
add eax,dword ptr ds:[esp+c]
add eax,dword ptr ds:[esp+10]
add eax,dword ptr ds:[esp+14]
RET 8是为了做堆栈平衡 含义是RET把当前堆栈中的值赋值给EIP,而8其实就是ESP+8,也就是让堆栈又回到原先的位置。
用户名 | 金币 | 积分 | 时间 | 理由 |
---|---|---|---|---|
Track-JARVIS | 10.00 | 0 | 2022-08-03 17:05:23 | 一个受益终生的帖子~~ |
打赏我,让我更有动力~
© 2016 - 2024 掌控者 All Rights Reserved.