最近学习魔幻野狼的汇编语言,有很多收获,趁热在这里记录汇编语言的常用指令,方便以后查找使用
注:以下代码中以h结尾的数都是十六进制数,以b结尾的数都是二进制数
另一方面,寄存器通用寄存器:可以用于存储数据/代码,其可以理解为高级语言中的变量。 与高级语言不同,cpu中的寄存器数通常是有限的,使用时需要计算。 一般的通用寄存器有AX、BX.CX.DX等
地址寄存器:是DS.ES.SS等存储专用地址,用于存储目的地地址
特殊寄存器:是具有CS是存储cpu指针专用段地址、IP是cpu指针的传送地址、SS是堆栈区域的段地址、SP是堆栈区域的传送地址等特殊意义的寄存器
标志寄存器
1 .溢出标志的操作数超出机器能够表现的范围时表示溢出,溢出时表示1. 2. SF sign Flag符号标志记录运算结果的符号, 如果结果为负,则1. ZF zero flag零标志如果运算结果为0,否则0. 3. CF carry flag进位标志的最高有效位为1,否则0.4.af auxiliary carry 如果从第3位到第4位发生进位,则为1,否则,如果0. 5. PF parity flag奇偶校验运算结果运算位数为1的个数且为偶数个,则为1,否则,0. 6. DF DIrecion flag方向标志用于串行处理如果DF=1,则每次操作后减少SI和di时,如果DF=0,7. if中断标志中断标志IF=1,则允许CPU中断。 否则,关闭中断.8. TF捕获标志并调试单步操作。 2 .指令mov:赋值指令,高级语言的’=’语法规则: mov寄存器,value eg: mov ax,相当于10h
inc:自增,相当于高级语言的’’语法规则:inc寄存器eg:inc ax
dec:自减法,高级语言的’’语法规则相当于:dec寄存器eg:dec ax
add:加法指令()、语法规则:add寄存器、寄存器/value eg: add ax、bx add ax、2,用于将两个数相加的结果存储在第一个寄存器中
sub:减法指令(-)、将两位减法结果保存到第一个寄存器的语法规则:sub寄存器、寄存器/value eg: sub ax、bx sub ax、2
mul:乘法指令(* )包括语法规则:mul寄存器、寄存器/value eg: mul ax、bx mul ax、2,其中第一个寄存器存储两个数字的乘法结果
div:除法指令(/)、语法规则:div寄存器、寄存器/value eg: div ax、bx div ax、2,用于将两个数字相除的结果存储在第一个寄存器中
adc:进制加法在计算较大数字(超过32位)时,低位保存在ax中,高位保存在dx中,可使用adc指令进行进位的运算有进位cf=1,否则
adc dx,0220h
sbb:借位减法在计算较大的数字(32位以上)时,低位保存在ax中,高位保存在dx中,用adc指令可以进行借位运算的是进位cf=1,否则cf=0,可以进行借位运算
sbb dx,0220h
jmp:分支命令可以手动指定cpu指定的地址(cs/ip )的代码语法规则: jmp short xxxx
jmp xxxx:xxxx (长跳) eg: JMP 1000H段内直接跳,跳地址偏移量为命令给出的JMP CX段内间接跳,跳地址偏移量为CX指出的JMP CX段偏移量
JMP DWORD PTR [SI]段之间的间接传输地址位于从SI指向的地址开始的四个单元
loop:循环指令、寄存器cx存储循环次数、从指定地址开始循环、高级语言while和for循环语法规则: loop目标地址eg: s: mov cx、3 add ax
条件分支指令:
命令英文语义格式条件JZ/JEjump if zero/equal结果为零/相等时JZ/jeoprzf=1jnz/jnejumpifnotzero/equal结果为零/不相等时JNZ/JNE OPRZF=0JSju
mp if sign结果为负则转移JS OPRSF=1JNSjump if not sign结果为正则转移JNS OPRSF=0JOjump if overflow溢出则转移JO OPROF=1JNOjump if not overflow不溢出则转移JNO OPROF=0JP/JPEjump if parity/parity even奇偶位为1则转移JP/JPE OPRPF=1JNP/JNPEjump if not parity/parity even奇偶位为0则转移JNP/JNPE OPRPF=0JB/JNAE/JCjump if below/not above、not equal/carry低于/不高于或不等于/进位为1则转移JB/JNAE/JC OPRCF=1JNB/JAE/JNCjump if not below/ above、equal/not carry不低于/高于或等于/进位为零则转移JNB/JAE/JNC OPRCF=0
ret/retf:返回指令
执行ret指令,相当于进行:pop IP,执行retf指令,相当于进行pop IP,pop CS
call:调用子程序指令,相当于高级语言中调用方法和函数
语法规则: call 子函数地址
eg:
#段内转移,相当于 #push IP#jmp near ptr 标号call func int 21hfunc: mov ax,4c00h ret #段间转移,相当于 #push CS #push IP #jmp far ptr 标号 mov sp,10h mov ax,0123h mov ds:[0],ax mov word ptr ds:[2],0 call dword ptr ds:[0] #调用 0000:0123h
pushf:将标志指令寄存器的值全部入栈
popf:将标志指令寄存器的值全部出栈
int:中断指令,可以令cpu在执行完当前指令后马上执行中断程序,中断程序的入口存放在0000:0000至0000:0200地址处,段地址=4n+2,转移地址=4n,其中n为int 后指定数值,int指令执行后会将 TF=0,IF=0,pushf, push cs, push ip
内中断:一般用于响应程序内部错误或由程序主动调用的中断处理,类似于高级语言中的try/catch
外中断:响应外设输入(鼠标/键盘等),外中断又称为可屏蔽中断,由状态寄存器IF控制,IF=1时,cpu响应外中断,IF=0则不响应
语法规则:int n
eg: int 21h
iret:中断返回指令,当cpu收到iret指令后,会执行
1.恢复IP(instruction pointer):(IP)←((SP)+1:(SP)),(SP)←(SP)+2
2.恢复CS(code segment):(CS)←((SP)+1:(SP)),(SP)←(SP)+2
3.恢复中断前的PSW(program status word),即恢复中断前的标志寄存器的状态。 (FR)←((SP)+1:(SP)),(SP)←(SP)+2
4.恢复ESP(返回权限发生变化)
5.恢复SS(返回权限发生变化)
push:入栈指令,8086型cpu中以ss为段地址,sp为转移地址,专门用于栈操作,当push指令执行时,会将数据(两个字节)压入栈,同时栈顶指针上移两位(sp=sp-2)
语法规则: push 寄存器
eg: 将地址段076a:0000 – 076a:0010 作为栈空间使用,将数据’1111h’压入栈
mov ax,076ahmov ss,axmov sp,16mov bx,1111hpush bx
pop:出栈指定,与入栈指定相反,执行后将栈顶数据赋值给寄存器,同时栈顶指针下移两位(sp=sp+2)
语法规则: pop 寄存器
es: pop ax
cmp:比较指定,用于比较两个数的大小,但不会改变两数的值,只会改变状态寄存器,可配置条件转移指定使用,相当于高级语言中的if
语法规则: cmp 寄存器a,寄存器b
eg:
# ax为0则转移到scmp ax,0je smov ax,1s:mov ax,2
and:与指令,将各个为上的值进行与比较,同时为1则为1,否则为0,相当于高级语言的‘&’
语法规则: and 寄存器a,寄存器b/值
eg:
mov ax,01101110bmov bx,10100010b and ax,bx # 最终结果为 ax=00100010b
or:或指令,将各个为上的值进行与比较,其中有一个为1则为1,否则为0,相当于高级语言的‘|’
语法规则:or 寄存器a,寄存器b/值
eg:
mov ax,01101110bmov bx,10100010b or ax,bx # 最终结果为 ax=11101110b
db/dw/dd:伪指令,由编译器识别,定义字节型/字型/双字型数据(define byte/word/double word)
db: value1,value2…
dw: value1,value2…
dd: value1,value2…
eg:
data segmentdb 1,’a’,4,$dw 0712h,0321h,0fe58hdd 0def89321h,00000000h,11111111hdata ends
dup:伪指令(duplicate),定义重复数据时使用
eg:
#定义一百个’a’
db 100 dup(‘a’)
nop:空指令,运行该指令时单片机什么都不做,但是会占用一个指令的时间
offset:由编译器处理,标识代码所在地址
eg:
#获取代码段start到end的长度(字节)mov ax,offset end-offset startstart: mov bx,0add bx,2mul bx,3end: nop
jcxz:条件转移指令,当cx=0时转移到指定位置,可用于实现loop循环,类似于高级语言的break
语法规则: jcxz 目标地址
eg:
mov ax,0mov bx,1mov cx,10s:add ax,bxinc bxjcxz okjmp sok:nop
movsb/movsw:串传送指令
1.传送的原始位置: ds:si
2.传送的目的位置: es:di
3.传送的长度: cx
4.传送的方向: df
eg:
#将字符串复制到后面的16位中data segmentdb ‘Welcome to masm!’db 16 dup(0)data endscode segmentmov ax,datamov ds,axmov si,0mov es,axmov di,16mov cx,16cldrep movsbcode ends
in/out:读/写端口指令,执行过程如下:
1.cpu通过地址线将地址信息xx发出
2.cpu通过控制线发出内存读命令,选中存储器芯片,并通知它,将要从中读取数据
3.存储器将8号单元中的数据通过数据线送入cpu
eg:
mov dx,3f8hin al,dxout dx,al
shl/shr:移位指令,左移一位相当于乘以2,右移一位相当于除以2
eg:
mov al,00110011b
shl al,1
#结果al=01100110b