最近在学习 16位汇编编程,所以顺便将每日所学记录下来,一方面为了巩固学习的知识,另一方面也为同样在学习汇编开发的童鞋们提供一份参考。
运行环境:
- 操作系统: Windows 10家庭版
- 编译器:Windows XP Debug
控制转移类指令
控制转移类指令用于实现分支、循环、过程等程序结构,是仅次于传送指令的最常用指令
重点掌握:JMP、JCC、LOOP、CALL、RET、INT n、IRET常用系统功能调用
一般了解:LOOPZ、LOOPNZ INTO
控制转移类指令通过改变IP(和CS)值,实现程序执行顺序的改变
JMP 无条件转移指令
- 只要执行无条件转移指令jmp,就使得程序转到指定的目标地址处,从目标地址处开始执行指令
- 操作数是要转移到的目标地址
- JMP指令分为四种类型:
- 段内转移、直接寻址
- 段内转移、间接寻址
- 段间转移、直接寻址
- 段间转移、间接寻址
位移量是紧接着JMP指令后的那条指令的偏移地址,到目标指令的偏移地址的地址位移;当向地址增大方向转移时,位移量为正;向地址减小方向转移时,位移量为负
1 |
|
寻址方式
直接寻址方式
- 转移地址像立即数一样,直接在指令的机器代码中,就是直接寻址;使用标号表达
间接寻址方式
- 转移地址在寄存器或主存单元中,就是通过寄存器或存储器的间接寻址方式;用寄存器或存储器表达
目标地址范围
段内
- 段内转移 - 近转移(near)
- 在当前代码段64KB范围内转移(+-32范围)
- 不需要改变CS段地址,只要改变IP偏移地址
1 | JMP label ;IP←IP+位移量 |
- 段内转移 - 短转移(short)
- 转移范围可以用一个字节表达,在段内-128~+127范围
1 | JMP r16/m16 ;IP←r16/m16 |
段间
- 段间转移 - 远转移(far)
- 从当前代码段跳转到另一个代码段,可以在1MB范围
- 需要更改CS段地址和IP偏移地址
- 目的地址必须用一个32位数表达,叫做32位远指针,它就是逻辑地址
1 | JMP far ptr label |
1.**实际编程时,汇编程序会根据目标地址的距离,自动处理成短转移、近转移或远转移**
2.**程序员可用操作符short、near ptr 或far ptr** 强制
条件转移指令
在指令手册中我们可以看到所有的JCC指令
1 | jcc label: |
- 指定的条件CC如果成立,程序转移到由标号lable指定的目的地址去执行指令;条件不成立,则程序将顺序执行下一条指令
- 操作数label是采用短转移,成为相对寻址方式
Tables | Are |
---|---|
Z/E | 相等 |
N | 非 |
S | 符号 |
P | 奇偶 |
O | 溢出 |
C | 进位 |
L | 小于(有符号数) |
G | 大于(有符号数) |
A | 高于(无符号数) |
B | 低于(无符号数) |
判断单个标志位状态
- 这组指令单独判断5个状态标志之一
⑴JZ/JE和JNZ/JNE:利用零标志ZF,判断结果是否为零(或相等)
⑵JS和JNS:利用符号标志SF,判断结果是正是负
⑶JO和JNO:利用溢出标志OF,判断结果是否产生溢出
⑷JP/JPE和JNP/JPO:利用奇偶标志PF,判断结果中“1”的个数是偶是奇
⑸JC/JB/JNAE和JNC/JNB/JAE:利用进位标志CF,判断结果是否进位或借位
- 这组指令单独判断5个状态标志之一
比较无符号数高低
- 无符号数的大小用高(Above)低(Below)表示
利用CF确定高低、利用ZF标志确定相等(Equal)
两数的高低分成4种关系:
⑴ 低于(不高于等于):JB(JNAE)
⑵ 不低于(高于等于):JNB(JAE)
⑶ 低于等于(不高于):JBE(JNA)
⑷ 不低于等于(高于):JNBE(JA )
- 无符号数的大小用高(Above)低(Below)表示
比较有符号数大小
- 有符号数的大(Greater)小(Less)需要组合OF、SF标志,并利用ZF标志确定相等(Equal)
两数的大小分成4种关系:
⑴ 小于(不大于等于):JL(JNGE)
⑵ 不小于(大于等于):JNL(JGE)
⑶ 小于等于(不大于):JLE(JNG)
⑷ 不小于等于(大于):JNLE(JG )
- 有符号数的大(Greater)小(Less)需要组合OF、SF标志,并利用ZF标志确定相等(Equal)
计算器CX为0转移
1 | JCXZ label |
这是一条较特殊的指令
CX寄存器通常在程序中用做计数器
JCXZ指令用来判断计数是否为0
循环指令
1 | LOOP label ;CX←CX-1, |
demo:
1 | mov cx,count ;设置循环次数 |