8086CPU地址總線寬度爲20, 也就是說一個內存物理地址是5位,內存地址空間爲1Mb;數據總線爲16位;寄存器爲16位。linux
16位結構的CPU包括如下特性:編程
1,運算符最多處理16位數據。windows
2,寄存器最大寬度爲16位。函數
3,寄存器與運算器之間的通路是16位。oop
這裏就出現了一個問題,若是由16位推出20位的物理地址呢?ip
因此就出現了段的概念:內存
一個物理地址由段地址和偏移地址構成,即物理地址=段地址*16 + 偏移地址編譯器
也能夠說段地址左移4位,而後咱們能夠推出偏移地址最大爲2的16次方,即16Kb.asm
這裏咱們要強調一個概念:編譯
CPU是死的,一點都不智能,對於它自己而言,並不知道什麼段的概念,段只是用來讓咱們編程者使用的,咱們能夠本身定義一個段的開始(定義CS或者DS),而後利用偏移地址靈活執行咱們寫的指令,這樣咱們就能夠避免指令在內存空間的互相掩蓋。
8086CPU不支持將一個數據直接寫到段寄存器中去。
8086的棧操做是以字爲單位的,這裏咱們仍是要強調一個概念:
CPU是死的,它纔不知道棧的概念呢,棧是咱們編程者本身在數據段裏開闢,而後咱們用pop,push彙編指令操做,一切都是咱們編程者操做出來的。
CPU是如何知道棧的地址呢?:
CPU纔不會知道呢,是咱們編程者本身首先定義好了一個棧段,而後咱們將這個棧段地址賦值到SS棧段寄存器中去,同時初始化SP寄存器。這樣之後咱們pop或者push一個字時,sp加2或者減2。仍是那句話,都是咱們編程者實現棧的功能,讓SS和SP永遠指向棧頂。
只有bx,si,di,bp這四個寄存器能夠進行內存單元尋址的,即[bx]這樣語法操做的,其中bx,bp這兩個寄存器不能同時出現,如[bx,bi],還有si,di這兩個寄存器也是不能同時出現的。
bp寄存器隱形的段地址是ss。如咱們這樣操做[ba],那麼是經過SS段地址尋址內存單元的。
寄存器尋址幾種方式:
1,直接尋址:[idata] idata 爲當即數
2,寄存器間接尋址: [bx] , 默認段地址是DS
3,寄存器相對尋址:[bx+idata] ,默認段地址是DS
4,基址變址尋址:[bx+si], 默認段地址DS
5,相對基址變址尋址:[bx+si+idata], SA是DS
指令要處理的數據長度問題:
對於這個問題,咱們要根據編程者本身的選擇的編譯器而定,像咱們在windows下用的都是Masm風格的彙編編程,在linux上則是使用AT&T風格的。
這裏是就masm風格而言,當咱們操做一個寄存器時,咱們根據寄存器的長度來肯定數據的長度,好比:
mov ax, [0]; 這裏咱們就是要操做的數據長度是16位的。
可是當沒有寄存器的時候,咱們就要經過標記符來肯定了。格式以下:
操做符 X ptr data, data; 這裏X ptr依據(X可使word或者byte)來指定操做數據長度。
像push和pop就不須要指定了,他們兩默認的是一個字。
div除法指令:被除數通常默認在AX或者BX中,或者就是32位的存儲在AX,BX中,而後除完以後,餘數在DX中,商在AX中
僞指令:
db:定義一個字節
dw:定義一個字
dd:double defined word 定義兩個字節
dup:與db,dw,dd配合使用,表示複製的意思,好比: db 3 dup(0);
轉移指令:
修改CS,IP或者僅僅修改IP的指令統稱爲轉移指令,好比:
jmp data,只修改ip
jmp SA:EA 修改cs和IP
offset操做符:
獲取一個標號的偏移地址,好比:
start:
mov ....
s:
mov ax, offset s; 此時至關於(mov ax, 1)
jmp指令:
jmp idata; jmp sa:ea; jmp short 標號(在段內短跳轉);jmp far ptr 標號(段間跳轉);jmp reg; jmp word ptr 內存單元地址(這裏是將那個內存單元裏的值給IP,段內轉移); jmp dword ptr 內存單元地址(段間跳轉,之內存單元地址所存的兩個字的高地址爲段地址,低地址爲偏移地址);
jcxz指令:
當cx=0 跳轉
loop指令:
至關於執行cx自減一,並前cx不等於0就跳轉,跳轉位移是8位,也就是說偏移地址在-128~127之間。
ret 指令:
有兩條指令:ret,retf指令
ret指令至關於pop IP
retf 至關於連續執行 pop IP; pop CS 兩條指令
call指令:
格式以下:
call 標號; 將當前IP壓棧,而後跳到標號處執行(改變IP值)
call far ptr 標號; 段間轉移
call reg(16位); 跳到IP=寄存器中的內容
call word ptr 內存單元地址; 跳到內存單元給定的值
call dword ptr 內存單元地址; 至關於執行:push CS; push IP; jmp dword ptr 內存單元地址;
call 和 ret通常配合使用,至關於調用了一個子函數。
mul乘法指令:
和div同樣,用到AX,DX寄存器
標誌寄存器:
裏面存儲的信息能夠稱爲PSW(程序狀態字),包括這些狀態:
第六位,ZF:標明執行結果是否爲0;
第二位, PF:奇偶標誌位:執行結果中若是1的個數爲偶數的話,則置1
第七位,SF:符號標誌位:結果爲負數則爲1
第零位,CF:進位借位標誌符:當最高有效位須要像更高位進位或者借位則置1(對於無符號位數)
第十一位,OF:溢出標誌位(對於有符號位數)
第十位:DF:方向標誌位:在串處理中,控制每次si,di的增減。DF爲0,則每次si,di遞減
串傳送指令:
movsb;
至關於執行以下指令:mov es:[di], byte ptr ds:[si]; 若是DF=0 ,則後續爲:inc si; inc di;
若是DF=1,則後續爲: dec si; dec di;
movsw;
每次傳送的是一個字
通常咱們傳送一個串的話選擇這樣的命令:
rep movsb;
至關於:
s: movsb;
loop s; 依據CX來判斷
pushf; popf; 將標誌寄存器壓棧或者彈出
條件轉移指令:
je: equal,若是等於了,則ZF=0,依ZF做爲判斷 jne: no equal
jb: below,若是第一個數小於第二個數,則CF=1 jnb; no below
ja: above jna: