ASM16 16 BCD码和控制转移类指令
BCD码
二进制编码的十进制数:一位十进制数用4位二进制编码来表示
8086支持压缩BCD码和非压缩BCD码的调整运算
真值 8 64 二进制编码 08H 40H 压缩BCD码 08H 64H 非压缩BCD码 08H 0604H
压缩BCD码加、减调整指令
- 使用DAA或DAS指令前,应先执行以AL为目的操作数的加法或减法指令
非压缩BCD码加、减调整指令
- 使用AAA或AAS指令前应先执行以AL为目的操作数的加法或减法指令
- AAA和AAS指令在调整中产生了进位或借位,则AH要加上进位或减去借位,同时CF=AF=1,否则CF=AF=0;它们对其他标志无定义
非压缩BCD码乘、除调整指令
- AAM指令跟在字节乘MUL之后,将乘积调整位非压缩BCD码
- AAD指令跟在字节除DIV之前,先将非压缩BCD码的被除数调整为二进制数
- AAM和AAD指令根据结果设置SF、ZF和PF,但对OF、CF和AF无定义
1 | mov al,19h ;bcd压缩码 19+1==>20 |
控制转移类指令
控制转移类指令用于实现分支、循环、过程等程序结构后,是仅次于传送指令的最常用指令
重点掌握:JMP/JCC/LOOP CALL/RET
INT n/IRET 常用系统功能调用
一般了解: LOOPZ/LOOPNZ INTO
无条件转移指令
1 | JMP label ;程序转向label标号指定的地址 |
- 只要执行无条件转移指令JMP,就使程序转到指定的目标地址处,从目标地址处开始执行那里的指令
- 操作数label是要转移到的目标地址(目的地址、转移地址)
- JMP指令分为4种类型:
- 段内转移、直接寻址
- 段内转移、间接寻址
- 段间转移、直接寻址
- 段间转移、间接寻址
目标地址的寻址方式
- 直接寻址方式(用标号表达)
- 转移地址像立即数一样,直接在指令的机器代码中,解释直接寻址方式
- 间接寻址方式(用寄存器或存储器操作数表达)
- 转移地址在寄存器或主存单元中,就是通过寄存器或存储器的间接寻址方式
目标地址的范围:段内
- 段内转移——近转移(near)
- 在当前代码段64KB范围内转移(-32KB~+32KB范围)
- 不需要更改CS段地址,只要改变IP偏移地址
- 段内转移——短转移(short)
- 转移范围可以用一个字节表达,在段内-128~+127范围的转移
段内转移、直接寻址
1 | JMP label ;IP<-IP+位移量(实际为相对寻址) |
- 位移量是紧接着JMP指令后的那条指令的偏移地址,到目标指令的偏移地址的地址位移
- 当向地址增大方向转移时,位移量为正;向地址减小方向转移时,位移量为负
段内转移、间接寻址
1 | JMP r16/m16 ;IP<-r16/m16 |
- 将一个16位寄存器或主存字单元内容送入IP寄存器,作为新的指令指针,但不修改CS寄存器的内容
目标地址的范围:段间
- 段间转移——远转移(far)
- 从当前代码段跳转到另一个代码段,可以在1MB范围
- 需要更改CS段地址和IP偏移地址
- 目标地址必须用一个32位数表达,叫做32位远指针,它就是逻辑地址
- 实际编程时,汇编程序会根据目标地址的距离,自动处理成短转移、近转移或远转移
- 程序员可用操作符short、near ptr或far ptr强制
段间转移、直接寻址
1 | JMP far ptr label ;IP<-label的偏移地址 CS<-label的段地址 |
- 将标号所在段的段地址作为新的CS值,标号在该段内的偏移地址作为新的IP值;这样,程序跳转到新的代码段执行
1 | MyData segment ;数据段 |
运行成功后会重复打印Hello World!
1 | ;控制转移类指令 |
0A和07代表跳转的偏移(7+2+A=13,9+3+7=13)
short的偏移为2个字节
near的偏移为4个字节
1 | LOOP1: |
F6为10的补码,E+3-10+7
1 | jmp LOOP1 ;伪指令 |
若省略short或near,则系统自动根据位移选择跳转方式
1 | MyCode2 segment |
077F即为MyCode2的基地址
成功跳转到MyCode2
1 | MyCode2 segment |
成功跳转回MyCode1
相对寻址方式
- Jcc指令的操作数label是一个标号
- 一个8位位移量,表示Jcc指令后的那条指令的偏移地址,到目标指令的偏移地址的地址位移
- 8位位移量是相对当前IP的,且距当前IP地址-128~+127个单元的范围之内,属于段内短距离转移
- Jcc目标地址就采用这种相对寻址方式
- Jcc指令为2个字节,条件不满足时的顺序执行就是当前指令偏移指针IP加2
1 | mov cx,10 |
每完成一次循环CX会自动减一
当CX为0时ZF为1,退出循环
1 | mov ax,1 ;if(ax==1) ax=0 |
ZF为1,说明AX==1,则不执行跳转,给AX赋值为0
条件转移指令中的条件cc
- 等于E(equal)
- 有符号:大于G(greater),小于L(less),大于等于jge,小于等于jle
- 无符号:大于A(above),小于B(below),大于等于jae ,小于等于jbe
判断单个标志位状态
- 这组指令单独判断5个状态标志之一
- JZ/JE和JNZ/JNE:利用零标志ZF,判断结果是否为零(或相等)
- JS和JNS:利用符号标志SF,判断结果是正是负
- JO和JNO:利用溢出标志OF,判断结果是否产生溢出
- JP/JPE和JNP/JPO:利用奇偶标志PF,判断结果中“1”的个数是偶是奇
- JC/JB/JNAE和JNC/JNC/JAE:利用进位标志CF,判断结果是否进位或借位
比较无符号数高低
- 无符号数的大小用高(Above)低(Below)表示
- 利用CF确定高低、利用ZF标志确定相等(Equal)
- 两数的高低分成4种关系:
- 低于(不高于等于):JB(JNAE)
- 不低于(高于等于):JNB(JAE)
- 低于等于(不高于):JBE(JNA)
- 不低于等于(高于):JNBE(JA)
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Hexo!