编程达人吧 关注:16贴子:35
  • 0回复贴,共1

2.3汇编指令

只看楼主收藏回复

本节主要内容:
1. 内存地址
2. 汇编语言的基础指令(push、pop、call)
老唐语录:
复合指令:
lea esp,[esp-4]
mov [esp],eax
使用vc6调试观察内存的变化:
这两条指令的组合就是我们学的新指令:push eax。
mov eax,[esp]
lea esp,[esp+4]就是指令pop eax。
练习:
将eax替换成其他7个寄存器并测试
总结:
pop ERX也可以理解为:
lea esp,[esp+4]
mov ERX,[esp-4]
所以pop esp可以简化为
lea esp,[esp+4]
mov esp,[esp-4]
练习:
在VC6中单步过程时,可以在代码窗口右键go to disassmbly,一步一步运行,并观察eip变化。
其实eip一直在变化。在80x86CPU中,eip寄存器指向的是将要执行代码的位置,代码本身也是数据,也是由二进制构成。
Intel指令的长度不同,最短的只占一个字节,最长15个字节。
比如:
xchg eax,eax
mov eax,0x1234567
通过VC6中的汇编窗口,右键code bytes,可以看见指令的二进制内容。
xchg eax,eax又称为nop。
数据包含代码,代码只是数据的一部分,eip指向的位置才称为代码。
前面提到计算机和数学(算盘)的不同点是计算机是定宽的。
第二个不同点是数学中的算盘只负责存储数据,并是由人操作的,而计算机相当于有两个算盘,其中一个存储数据,另一个负责操作算盘。
操作和运算本身也是代码,并存在于内存中。但是代码本身不能存放在寄存器,只能放在内存中,只有数据可以放在寄存器中。但是专门有一个寄存器负责指向执行代码(操作算盘的人在哪里,在内存中的哪个位置)。eip是寄存器,所以他的值可以被改变。
计算机取名字是有规则的,以字母、数字或下划线组成,并且不以数字开始。
mov eax,offset 标号名(标签);用名字的时候要加个offset,其实就是立即数
每个地方都可以取个标签,如:
lab: mov eax,ecx
mov ecx,offset lab
既然汇编指令就是在寄存器和内存间移动指令,那么我们可以使用mov来修改eip:
mov eip,寄存器/立即数
简写为 (取别名):
jmp 寄存器/立即数
此外,
push offset lab
mov eip,eax
lab :...
称为call eax
ret 就是
lea esp,[esp+4]
mov eip,[esp-4]//jmp [esp-4]
的简写形式。
ret 后面可以加一个数0x04,0x08……这个数是两个字节的宽度:
ret IW,比如ret 0x4
课后理解:
·PUSH:压入堆栈,见图2-6:
图2-6:PUSH指令图解
esp指向的堆栈首地址,位置在内存中。由图2-6得出,所以当需要往堆栈中添加值时,堆栈首先要减4个字节(因为堆栈增长方向是由高地址到低地址),然后将值填入新位置。
简化PUSH eax:
说明:
sub esp,4
mov esp,eax
·POP:弹出堆栈
图2-7:POP指令图解
弹出堆栈与压入堆栈的操作相反。由图2-7得出:将要弹出的当前堆栈值赋给寄存器,然后堆栈加四个字节。POP eax可以简化成:
mov eax,[esp];
add esp,4;
课后疑问:
POP ESP 是否也可以简化为指令方式?
说明:如果按上述的公式则写成
mov esp,[esp];
add esp,4;
可以看出,第一条汇编指令中得到的esp值被第二条指令修改,所以直接将esp带入是错误的。因为pop eax又可以等价于:
add esp,4
mov eax,[esp-4]
所以答案是:
add esp,4
mov esp,[esp-4]
课后总结:
操作和运算本身也是代码,并存在于内存中。
课后练习:
1. 以下代码在纸上抄写10遍(目的抄会)
PUSH EAX
MOV DWORD PTR DS:[ESP-4],EAX
LEA ESP,DWORD PTR DS:[ESP-4]
POP ECX
LEA ESP,DWORD PTR DS:[ESP+4]
MOV ECX,DWORD PTR DS:[ESP-4]
2. PUSH ERX
POP ERX
ERX做各种测试;单步执行语句,查看寄存器和内存的变化,且写出规律;
执行这些指令的时候 ESP都是等于 0012FF34,这是什么原因呢?可以为其他的吗?


1楼2016-06-09 19:53回复