1、內存中字的存儲
CPU
中,用 16
位寄存器來存儲一個字,高 8
位放在高位字節(jié),低 8
位放在低字節(jié)。比如我們從 0
地址開始存放 20000
,如下圖所示,在圖中用 0
和 1
兩個內存單元來存儲 20000(4E20H)
, 0
和 1
這兩個單元可以看做一個起始地址為 0
的字單元,則數(shù)據(jù) 4E20H
的低位字節(jié)放在 0
號單元中,高位字節(jié)存放在 1
號單元中。
2、mov、add、sub 指令
mov
指令有以下幾種形式
mov 寄存器,數(shù)據(jù) 如:mov ax,6
mov 寄存器,寄存器 如:mov ax,bx
mov 寄存器,內存單元 如:mov ax,[0]
mov 內存單元,寄存器 如:mov [0],ax
mov 段寄存器,寄存器 如:mov ds,ax
注:mov 內存單元,內存單元 如:mov [0],[1] 這是錯誤的寫法,mov 指令不能用內存地址直接對內存地址賦值
3、棧
棧是一種具有特殊的訪問方式的存儲空間,遵循后進先出的規(guī)則。8086
CPU
用 SS:SP
指示棧頂?shù)奈恢茫⑻峁?push
和 pop
指令實現(xiàn)壓棧和出棧。push
和 pop
指令有以下幾種形式
push 寄存器 push ax 將寄存器 ax 的數(shù)據(jù)壓入棧中
pop 寄存器 pop ax 從棧頂取出數(shù)據(jù)送入 ax
注:8086 CPU 的壓棧和出棧操作都是以字節(jié)為單位進行的。
4、loop 指令
英文單詞 loop
有循環(huán)的意義,顯然這個指令和循環(huán)有關。loop
指令格式:loop 標號
,CPU
執(zhí)行 loop
指令的時候,要進行兩部操作
1. sub cx,1H 先將 cx 減一
2. 判斷 cx 中的值,不為零則跳轉至標號處執(zhí)行程序,為零則向下執(zhí)行。
例:add ax,ax 需要重復執(zhí)行 10 次
mov cx,10
s: add ax,ax
loop s
5、mul、div 指令
mul
乘法指令
(1)兩個相乘的數(shù)要么都是 8
位,要么都是 16
位;如果是 8
位,一個存放在 al
中,另一個存放在 8
位的寄存器或者內存字節(jié)單元中;如果是 16
位,一個默認值 ax
中,另一個放在 16
位寄存器或內存單元字中。
(2)結果:如果是 8
位乘法,結果默認放在 ax
中;如果是 16
位乘法,結果高位默認在 dx
中,地位在 ax
中。
指令格式:mul 寄存器 如:mul ax
mul 內存單元 如:mul byte ptr ds:[0]
div
除法指令
(1)除數(shù):有 8
位和 16
位兩種,在一個寄存器或內存單元中;
(2)被除數(shù):默認放在 ax
或 dx
和 ax
中,如果除數(shù)為 8
位,則被除數(shù)為 16
位,默認存放在 ax
中,如果除數(shù)為 16
位,被除數(shù)則為 32
位, dx
存放高 16
位, ax
存放低 16
位。
(3)結果:如果除數(shù)為 8
位,則 al
存儲除法操作的商, ah
存儲除法操作的余數(shù),如果除數(shù)為 16
位,則 ax
存儲除法操作的商, dx
存儲除法操作的余數(shù)。
指令格式:div 寄存器 如:div ax
div 內存單元 如:div word ptr ds:[0]
6、偽指令db、dw、dd、dup
db = define byte 定義數(shù)據(jù)寬度為一個字節(jié)
dw = define word 定義數(shù)據(jù)寬度為一個字
dd = define duble word 定義數(shù)據(jù)寬度為兩個字
dup
是一個操作符,它是配合 db
dw
dd
等數(shù)據(jù)偽指令一起使用的,用來數(shù)據(jù)的重復。
指令格式:db 重復次數(shù) dup(重復的字節(jié)型數(shù)據(jù))
指令格式:dw 重復次數(shù) dup(重復的字型數(shù)據(jù))
指令格式:dd 重復次數(shù) dup(重復的雙字型數(shù)據(jù))
db 3 dup(0,1,2)
定義了 `9` 個字節(jié),相當于 `db 0,1,2,0,1,2,0,1,2`
7、offset 操作符
操作符 offset
在匯編語言中是由編譯器處理的符號,它的功能就是取得標號的偏移地址,比如下面的程序
assume cs:code
codesg segment
start: mov ax,offset start ;相當于 mov ax,0
s: mov ax,offset s ;相當于 mov ax,3
codesg ends
end start
在上面的程序中,offset
操作符取得了標號 start
和 s
的偏移地址 0
和 3
,因為第一條指令的長度為 3
個字節(jié),則 s
的偏移地址為 3
。
8、轉移指令
可以修改 IP
或者同時修改 CS
和 IP
的指令統(tǒng)稱為轉移指令,概括的講,轉移指令就是可以控制 CPU
執(zhí)行內存中某處代碼的指令。
8086 CPU 的轉移行為有以下幾類
* 只修改 IP 時,稱為段內轉移,比如:jmp ax
* 同時修改 CS 和 IP 時,稱為段間轉移,比如:jmp 1000:10
由于轉移指令對 IP 的修改范圍不同,段內轉移又分為以下兩種情況
* 短轉移 IP 的修改范圍為 -128~127
* 近轉移 IP 的修改范圍為 -32768~32767
8086 CPU 的轉移指令有以下幾類
* 無條件轉移指令,如:jmp
* 條件轉移指令,如:jz
* 過程
* 中斷
jmp
指令格式
jmp short 標號 實現(xiàn)段內短轉移
jmp near ptr 標號 實現(xiàn)段內近轉移
jmp far ptr 標號 實現(xiàn)段間轉移,又稱為遠轉移
jmp word ptr 內存單元地址(段內轉移)
jmp dword ptr 內存單元地址(段間轉移)
功能:從內存單元地址處放著兩個字,高地址處的字是轉移的目的段地址,低地址處是轉移目的偏移地址。
8、call 和 ret 指令
ret
指令用棧中的數(shù)據(jù),修改 IP
的內容,從而實現(xiàn)近轉移;retf
指令用棧中的數(shù)據(jù),修改 CS
和 IP
的內容,從而實現(xiàn)遠轉移;
CPU 執(zhí)行 ret 指令時,進行下面 2 步操作
1、(IP) = ((ss)* 16 + (sp))
2、(sp) = (sp) + 2 相當于 pop ip
CPU 執(zhí)行 retf 指令時,進行下面 4 步操作
1、(IP) = ((ss)* 16 + (sp))
2、(sp) = (sp) + 2 相當于 pop ip
3、(CS) = ((ss)* 16 + (sp))
4、(sp) = (sp) + 2 相當于 pop cs
call
不能實現(xiàn)短轉移,除此之外,call
指令實現(xiàn)轉移的方法和 jmp
指令的原理相同,主要進行兩個步驟
1、將當前的 `IP` 或 `CS` 和 `IP` 壓入棧中
2、轉移