經過學習。對8086匯編經常使用指令進行了下面總結:
(1).mov : 移動數據
比如:
mov ax, 8h ;mov 寄存器,常量 mov ax, bx ;mov 寄存器,寄存器 mov ax, ds:[0] ;mov 寄存器。內存單元 mov ds:[0], ax ;mov 內存單元,寄存器 mov ds, ax ;mov 段寄存器,寄存器 mov word ptr ds:[0], 8h ;mov (內存單元大小聲明) 內存單元, 常量 sk: mov ax, offset sk ;mov 寄存器,標號偏移地址 mov byte ptr ds:[0], offset sk ;mov 內存單元,標號偏移地址
易錯點:
mov ds:[0], ds:[1] ;mov 內存單元,內存單元(非法指令) mov ds, 8h ;mov 段寄存器,常量(非法指令) mov ds, es ;mov 段寄存器。段寄存器(非法指令) mov ds, offset sk ;mov 段寄存器。標號偏移地址(非法指令) mov [0], ax ;常量偏移地址不可省略默認ds,必須作段地址聲明(非法指令)
(2).add:添加數據值。使用方法同mov類似
(3).sub:降低數據值,使用方法同mov類似
(4).push:入棧,棧頂指針(sp)=(sp)+2,,並將一個字數據存入sp所指內存單元
比如:
push ax ;push 寄存器 push ds:[0] ;push 內存單元易錯點:
push al ;push 寄存器(高/低)字節(非法指令)。必須是一個字。16位數據 push 8h ;push 常量(非法指令)
(5).pop:出棧,讀取一個字sp所指的內存單元。並使棧頂指針(sp)=(sp)-2
比如:
pop ax ;pop 寄存器 pop ds:[0] ;pop 內存單元
易錯點:
pop al ;pop 寄存器(高/低)字節(非法指令),必須是一個字,16位數據 pop 8h ;pop 常量(非法指令)
(6).inc:數據值+1, dec:數據值-1
比如:
inc ax ;inc 寄存器 inc byte ptr ds:[0] ;inc (大小聲明)內存單元 dec ax ;dec 寄存器 dec byte ptr ds:[0] ;dec (大小聲明)內存單元
易錯點:
inc 8h ;inc 常量(非法指令) dec 8h ;dec 常量(非法指令)
(7).jmp:無條件轉移指令
比如:
s: jmp short s ;段內短轉移,jmp short 標號,IP改動范圍-128~127 jmp near ptr s ;段內近轉移,jmp near ptr 標號, IP改動范圍-32768~32767 ;以上兩條指令的實質為保存IP到標號的偏移距離,注意正確使用 jmp far ptr s ;段間轉移(遠轉移)。jmp far ptr s, 改動CS:IP為標號的段地址:偏移地址 jmp ax ;段內轉移。jmp 16位reg, (IP)=(16位reg) jmp word ptr ds:[0] ;段內轉移,jmp word ptr 內存單元地址, ;(IP)=(內存單元地址處雙字節內存) jmp dword ptr ds:[0] ;段間轉移,jmp dword ptr 內存單元地址, ;(IP)=(內存單元地址處低16位內存數據),(CS)=(內存單元地址處高16位內存數據)
易錯點:
jmp 1000:0 ;想轉移到(cs:ip)=(1000:0)處(非法指令) jmp offset s ;想轉移到標號s處(非法指令)
(8).jcxz:有條件轉移指令,等價於
if((cx)==0) jmp short 標號;
(9).loop:循環指令,等價於
(cx)--; if((cx)!=0)jmp short 標號;
(10).and:二進制與運算。同mov,add,sub使用方法相似
(11).or:二進制或運算, 同mov,add,sub使用方法相似
比如:
and ds:[0], 1111h ;and 內存單元 and ax, 1111h ;and 16位寄存器 常量 and al, 11111110b ;and 8位寄存器 常量(第0位設為0) and ax, bx ;and 16位寄存器。16位寄存器 ;等等... or ds:[0], 1111h ;or 內存單元 or ax, 1111h ;or 16位寄存器 常量 or al, 00000001b ;or 8位寄存器 常量(第0位設為0) or ax, bx ;or 16位寄存器,16位寄存器 ;等等...
(12).mul:乘法指令
;(1)兩個相乘的數:兩個相乘的數。要么都是8位,要么都是16位。假設是8位。 ;一個默認放在AL中,還有一個放在8位reg或內存字節單元中;假設是16位,一個默認在 ;AX中,還有一個放在16位reg或內存單元中。 ;(2)結果:假設是8位乘法,結果默認放在AX中;假設是16位乘法,結果高位默認在 ;DX中存放,低位在AX中放。
;計算100*10 mov al, 100 mov bl, 10 mul bl ;結果:(ax)=1000(03E8h) ;計算100*10000 mov ax, 100 mov bx, 10000 mul bx ;結果:(ax)=4240H, (dx)=000FH (F4240H=1000000)
(13).div:除法指令
;除數:有8位和16位兩種,在一個reg或內存單元中 ;被除數:默認放在AX或DX和AX中,假設除數為8位,被除數則為16位。 ;默認在AX中存放;假設除數為16位,被除數位32位,在DX和AX中存放,DX存 ;放高16位,AX存放低16位 ;結果:假設除數為8位。則AL存儲除非操作的商,AH存儲除非操作的余數; ;假設除數為16位,則AX存儲除法操作的商。DX存儲除法操作的余數 ;計算100001/100 mov dx, 1 mov ax, 86A1H ;(dx)*10000H+(ax)=100001 mov bx, 100 div bx ;結果:(ax)=03E8H(即1000),(dx)=1(余數為1) ;計算1001/100 mov ax, 1001 mov bl, 100 div bx ;結果:(al)=0AH(即10),(ah)=1(余數為1)
(14)call 標號:等價於
push IP jmp near ptr 標號
(15)ret : 等價於
pop IP因此常如此配合使用:
call program1 program1: ;........ ret
(16)call far ptr 標號:等價於
push CS push IP jmp far ptr 標號
(17).retf:等價於
pop IP pop CS因此常如此配合使用:
call far ptr program2 program2: ;........ retf
(18)call word ptr 內存地址:等價於
push IP jmp word ptr 內存地址 ;比如: mov sp, 10h mov ax, 0123h mov ds:[0], ax call word ptr ds:[0] ;結果:(IP)=0123H, (SP)=0EH
(19)call dword ptr 內存地址:等價於
push CS push IP jmp dword ptr 內存單元地址 ;比如: mov sp, 10h mov ax, 0123h mov ds:[0], ax mov word ptr ds:[2], 0 call dword ptr ds:[0] ;結果:(CS)=0,(IP)=0123H,(sp)=0CH
(20)shl:邏輯左移指令
;(1)將一個寄存器或內存單元中的數據向左移位; ;(2)將最后移出的一位寫入CF中 ;(3)最低位用0補充 ;比如: mov al, 01001000b shl al, 1 ;結果:(al)=10010000b, CF=0 ;若移動位數大於1,則必須將移動位數放在cl中 mov al, 01010001b mov cl, 3 shl al, cl ;結果:(al)=10001000b, 由於最后移除的一位是0,所以CF=0
(21)shr:邏輯右移指令
;(1)將一個寄存器或內存單元中的數據向右移位; ;(2)將最后移出的一位寫入CF中 ;(3)最高位用0補充 ;比如: mov al, 10000001b shr al, 1 ;結果:(al)=01000000b, CF=0 ;若移動位數大於1。則必須將移動位數放在cl中 mov al, 01010001b mov cl, 3 shr al, cl ;結果:(al)=00001010b, 由於最后移除的一位是0,所以CF=0
(22)int 常量:中斷例程
總結:
由上述能夠看出8086匯編有下面語法規律:
(1)指令格式有3種形式:
指令 目標 源
指令 目標
指令
(2)除int指令外,“目標”不能為常量
(3)當“目標”為段寄存器時。“ 源”僅僅能為寄存器
(4)"目標“和"源"所占的內存字節大小應保證同樣,
當兩方顯式知曉內存字節大小時,若不同樣,則無法通過編譯。
當僅有一方知曉內存字節大小時,數據處理則按該方內存字節大小計算,
當兩方都不知曉內存字節大小時,應用byte/word/dword ptr顯示聲明,當中dword ptr僅用於一些特殊指令。
(5)轉移指令有直接設置和位移偏移兩種。當中位移偏移有距離限制。