MOV指令
作用:数据移动
mov cx,ax // 将ax寄存器中的值复制到cx寄存器中
mov dx,FFFF // 将数据0xFFFF放到寄存器dx中
mov al,bh // 将bx寄存器的高八位的数据复制到ax寄存器的低八位
NOP:空指令
指令、数据对齐可以有效地提高程序的性能, 使用 NOP 指令,可以使得指令按字对齐,从而提高效率 。
比如一条指令占用 3 个字节,再加上一个 NOP 指令,就使得指令 4 字节对齐了
运算指令
ADD指令:加
作用:加法
add ax,bx // ax寄存器的值加上bx寄存器的值,结果放到ax寄存器中
add bx,ff // bx寄存器的值加上0xff,结果放到bx寄存器中
add cl,11 // cx寄存器的低8位加上0x11,结果放到cx寄存器的低八位里面
注意:假设计算的结果超过了寄存器的位数时,多出来的高位会被舍弃。或者说当计算的值超过超过寄存器可容纳的最大值(16位寄存器最大值是0xFF)后,寄存器会从0开始计算(0xffff+1 = 0;0xffff+2 = 1)
例如:0xCDEF + 0xEFDD = 0x1BDCC
但是寄存器只会保留0xBDCC,如下图
只计算低八位的需要进位时,也不会向高位进位,会直接舍弃
SUB指令:减
作用:减法
注意:当被减数小于减数时,被减数会向前借位。或者说被减数被减到0x00后,再减就会变成0xff
示例:
sub ax,bx // ax寄存器减去bx寄存器,结果放到ax寄存器中
sub bx,33 // bx寄存器减去0x33,结果放到bx寄存器中
sub cl,bh // cx寄存器的低八位减去bx寄存器的高八位,结果放到cx寄存器的低八位
MUL指令:乘
作用:乘法
注意:
-
两个相乘的数:两个相乘的数,要么都是8位,要么都是16位。如果是8位,一个默认放在AL中,另一个放在8位reg或内存字节单元中;如果是16位,一个默认在AX中,另一个放在16位reg或内存字单元中。
-
结果:如果是8位乘法,结果默认放在AX中:如果是16位乘法,结果高位默认在DX中存放,低位在AX中放。
示例:
-
2个8位数相乘(小于255):0x64 * 0x0a = 0x03e8 (100 * 10)
mov al,64 // ax寄存器低八位设置为0x64 mov bx,a // bx寄存器设置为0x0a mul bx // bx寄存器的值乘以al寄存器的值,结果放到ax寄存器中
-
2个16位数相乘:0x03e8 * 0x03e8= 0xF4240 (1000*1000)
mov ax,3e8 // ax寄存器设置为0x3e8 mov bx,3e8 // bx寄存器设置为0x3e8 mul bx // ax的值乘以bx的值,结果的高16位放到dx,低16位放到ax
DIV指令:除
作用:除法
注意:
- 除数:有8位和16位两种,在一个reg或内存单元中。
- 被除数:默认放在AX或DX和AX中,如果除数为8位,被除数则为16位,默认在AX中存放;如果除数为16位,被除数则为32位,在DX和AX中存放,DX存放高16位,AX存放低16位。
- 结果:如果除数为8位,则AL存储除法操作的商,AH存储除法操作的余数:如果除数为16位,则AX存储除法操作的商,DX存储除法操作的余数。
示例:
-
8位除法:23 / 5 = 4 ... 3 (0x17 / 0x05)
mov ax,17 // 设置被除数为0x17 mov bl,5 // 设置除数为8位的0x05 div bl // 计算0x17 / 0x05。结果的商在al,余数在ah
-
16位除法:305419896 / 61166 = 4993 ... 18058 (0x12345678 / 0xEEEE)
mov dx,1234 // 设置被除数的高16位 mov ax,5678 // 设置被除数的低16位 mov bx,eeee // 设置除数 div bx // 相除。结果的商放在ax,余数放在dx
AND指令:与
作用:按位与运算
示例:0x4f与0xef进行与运算
mov al,4f
and al,fe // al的值按位与0xfe,结果放到al中
OR指令:或
作用:按位或运算
示例:0xac与0x01进行或运算
mov al,ac
or al,01 // al的值按位或0x01,结果放到al中
SHL指令:左移
作用:普通左移,将最后移出的一位写入:CF中,低位补0
注意:如果移动的位数大于1,则必须将移动位数放到cl中
示例:
-
移动一位
0xffff左移一位
mov ax,ffff shl ax,1 // ax的值左移一位,结果放到ax中
-
移动多位
0xffff左移3位
mov ax,ffff mov cl,3 // 要移动的位数大于1时,要放到cl中 shl ax,cl // ax的值左移3位,结果放到ax中
SHR指令:右移
作用:普通右移,将最后移出的一位写入:CF中,高位补0
注意:如果移动的位数大于1,则必须将移动位数放到cl中
与左移同理,只不过移动的方向相反
ROL指令:不带进位的循环左移
作用:向左移,最后移出来的一位写入CF中,并且回到最低位
注意:如果移动的位数大于1,则必须将移动位数放到cl中
示例:
-
0x80向左移动一位
mov al,80 rol al,1 // al中的值循环左移一位,结果放到al中
-
0x80向左移动4位(交换高四位和第四位)
mov al,80 mvo cl,4 // 要移动的位数放到cl中 rol al,cl // al的值循环左移4次,结果放到al中
ROR指令:不带进位的循环右移
作用:向右移,最后移出来的一位写入CF中,并且回到最高位
注意:如果移动的位数大于1,则必须将移动位数放到cl中
其他与循环左移同理
RCL指令:带进位的循环左移
作用:左移, 将CF位放到目标操作数的最左边,一起参与循环,从CF位移出去的数字循环回最低位
注意:如果移动的位数大于1,则必须将移动位数放到cl中
示例:
0x80带进位循环左移两次
mov al,80
rcl al,1
rcl al,1
RCR指令:带进位的循环右移
作用:右移,将CF位放到目标操作数的最右边,一起参与循环,从CF位移出去的数字循环回最高位
注意:如果移动的位数大于1,则必须将移动位数放到cl中
其他与带进位循环左移同理
NEG指令:求补
作用: 求补运算,即用零减去操作数,然后将结果返回给操作数。这个过程也可以理解为将操作数按位取反后再加1。NEG指令通常用于求一个数的相反数,也就是它的补码。
NEG指令的工作原理:
-
按位取反加一:首先,将操作数转换为补码表示,然后按位取反,最后在末位加1。例如,如果操作数是正数64h(二进制0110 0100),按位取反后得到1001 1011,再加1得到1001 1100,即9ch,这就是-64h的补码表示。
-
从运算角度:可以将NEG指令看作是0减去操作数的运算。例如,如果操作数是64h,那么
neg al
相当于0 - 64h = -64h
。如果操作数是-8,那么neg al
相当于0 - (-8) = 8
。这种方法对于操作数为负数的情况更为简便,相当于直接求绝对值。
示例:对0xff08求补
mov ax,ff08
neg ax // 对ax中的值求补,结果放到ax中
INC指令:自增
作用:自增
注意:超过最大值后会归零,或者说向前进了一位,但是进的位被舍弃了
示例:
mov al,fc
inc al // al的值自增1,结果放到al中
inc al // al的值自增1,结果放到al中
DEC指令:自减
作用:自减
注意:等于0后还减会等于最大值,或者说向前借了一位
示例:
mov al,01
dec al // al的值自减1,结果放到al中
dec al // al的值自减1,结果放到al中
XCHG指令:交换值
作用: 交换两个数据的内容
注意:
- 不能交换两个内存操作数,只能寄存器与寄存器,寄存器与内存操作数。如果要交换两个内存操作数,需要用寄存器做临时容器,mov和xchg一起使用
- 两个交换的数的大小必须一致,8位和8位交换,16位和16位交换,不能8位和16位交换
示例:交换ax和bx
mov ax,1111
mov bx,2222
xchg ax,bx // 交换ax和bx
标签:汇编,常用,al,mov,指令,寄存器,ax,bx
From: https://www.cnblogs.com/liuhousheng/p/18515600