彙編筆記
能夠被計算機直接識別的語言稱之為機器語言,比如: 00100000
這種的,組合語言是需要通過編譯器轉變為機器語言的。
計算機構成:輸入/輸出裝置、儲存器、運算器、控制器
1.基礎單位資訊
bit=位 1/0 計算機最小資訊單位
Byte=位元組=8bit=B=1個儲存單元 計算機最小儲存單位
字(word)=2B=2byte
儲存地址和儲存內容一般用16進製表示
0x..或者H=十六進位制(0,F) B=二進位制(0,1) D=十進位制(0,9)
2.CPU對儲存器的讀寫
ROM=>BOIS晶片
CPU通過地址匯流排定址、資料匯流排傳輸資料、控制匯流排進行操作來完成一些處理。
地址對應的是資料,因此地址匯流排的寬度也就是其一次最大能尋找到多少個位元組的資料。
不同CPU的暫存器個數是不同的,但是都有通用暫存器
3.暫存器
概念:CPU中程式員可以用指令讀寫的部件,暫存器數量有限(8086中有14個暫存器),讀寫速度快。
記憶體單元是一個單元存放一個位元組(8位二進位制)
通用暫存器可用於傳送和暫存資料,也可參與算術邏輯運算,並儲存運算結果。除此之外,它們還各自具有一些特殊功能。
資料是不能直接送入段地址暫存器(DS)中的;
16位暫存器可以拆分為兩個8位暫存器進行使用;
mov a1,[0]
,此處的[]說明操作的是一個記憶體單元,[0]中的0說明這個記憶體單元的偏移地址是0,它的段地址預設放在ds暫存器中,使用時會被去出來。
PS:
累加暫存器在不同位計算機中的名字不同 16位-AX 32位-EAX 64位-RAX
16位資料暫存器不能存放資料地址,但是32位的可以
3.1 資料暫存器
3.2 標誌暫存器
3.2.1運算結果標誌位
ZF標誌(ZeroFlag):
零位標誌位,它記錄相關指令執行後的結果是否為0,如果是0,那麼ZF=1,如果結果不為0,那麼ZF=0。
PF標誌(ParityFlag):
奇偶標誌位,它記錄相關指令執行後,其結果的所有二進位制位中1個個數是否為偶數,如果是偶數,PF=1,反之為0。
SF標誌(SignFlag):
符號標誌位,它記錄相關指令執行後,其結果是否為負,如果結果為負,SF=1,如果非負,SF=0。
CF標誌(Carry進位,Flag標誌):
進位標誌位,一般情況,進行無符號運算時,它記錄運算結果的最高位向更高位的進位值,或從更高位的借位值,如果運算結果的最高位產生了一個進位或借位,那麼其值為1,否則其值為0。
OF標誌(Overflow溢位,Flag標誌):
溢位標誌位,在進行有符號數運算的時候,如果結果超出了機器所能表示的範圍稱為溢位,OF的值被置為1,否則OF的值為0。
注意:這裡所說的溢位,只是對有符號運算而言。
3.2.2狀態控制標誌位
TF標誌(TrapFlag):
追蹤標誌位,當追蹤標誌被置為1時,CPU進入單步執行方式,即每執行一條指令產生一個單步中斷請求,這中方式主要用於程式的除錯。
IF標誌(Interrupt-enable Flag):
中斷允許標誌位,用來決定CPU是否響應CPU外部的可遮蔽中斷髮出的中斷請求,但不管該標誌為何值,CPU都必須響應CPU外部的不可遮蔽中斷所發出的中斷請求,以及CPU內部產生的中斷請求。
當IF=1時,CPU可以相應CPU外部的可遮蔽中斷髮出的中斷請求。
當IF=0時,CPU不響應CPU外部的可遮蔽中斷髮出的中斷請求。
CPU的指令系統中也有專門的指令來改變標誌位IF的值。
4.實體地址
通常檔案中至少含有兩個段:程式碼段(儲存程式的指令–可讀,不可寫,可執行)、資料段(儲存需要的資料的指令–可讀,可寫,可執行)
二進位制左移N位相當於這個二進位制數乘以2的N次方
實體地址=段地址*16(又稱基址)+偏移地址
任何時刻8086CPU都會將CS:IP指向的內容作為即將執行的指令(可以使用 jmp
對其進行修改操作)
一個實體地址可以對應多個邏輯地址,在程式設計的時候使用的是邏輯地址(=段基地址+段內偏移地址)
5.段地址
可以將若干地址連續的記憶體單元看做一個段
8086CPU有4個段暫存器,每個段暫存器用來確定一個邏輯段的起始位置,每種邏輯段均有各自的用途:
CS(程式碼段):指明程式碼的起始地址
利用CS:IP取得下一條要執行的指令
SS(堆疊段):指明堆疊段的起始地址
利用SS:SP操作堆疊頂的資料
DS(資料段):指明資料的起始地址
利用DS:EA存取資料段中的資料
ES(附加段):指明附加段的起始地址
利用ES:EA存取附加段中的資料
PS:
1.在記憶體中,指令和資料沒有任何區別,都是而二進位制資訊,只是CPU將有的資料看成指令,有的看成資料
2.一般的暫存器,如AX,可以使用 mov ax,123
來完成對其中數值的修改。但是像CS,IP這樣的暫存器(用來從記憶體中定址執行指令的)只能使用轉移指令來修改,比如jmp– jum [段地址:]偏移地址
,段地址和’:’預設將只修改IP的值
3.操作中如果沒有指明段字首,則一般訪問的是DS
mov ax,[1000H] ;這兩行都是等價的 mov ax,ds:[1000H]
6.mov,add,sub指令
mov 暫存器,資料 比如: mov ax,8 mov 暫存器,暫存器 比如: mov ax,bx mov 暫存器,記憶體單元 比如: mov ax,[0] mov 記憶體單元,暫存器 比如: mov [0],ax mov 段暫存器,暫存器 //相反也對 比如: mov ds,ax
關於mov的操作物件的說明:

PS:
指令=操作碼(+運算元)
7.棧(後入先出)
兩個關鍵暫存器:SS,SP->段地址,段偏移地址。這對暫存器將會指出棧頂地址。棧大小由我們自己安排所以要小心超界問題。
mov ax,0123H psuh ax mov bx,2266H push bx pop ax //2266H pop bx //0123H
PS:
堆疊操作都是以字(2位元組)為單位操作的。
8.開發環境配置
win7及以上系統都沒有debug了,所以都需要這個DOSBOX
ofollow,noindex">MAC OS環境下DOSBOX彙編環境的搭建
9.debug
功能:
- 可以檢視CPU暫存器的各種內容
- 可以檢視記憶體的使用情況
- 可以在機器碼級別跟蹤程式的執行
常用操作:

二、程式
0.程式執行
1.程式載入到記憶體
2.CPU使用暫存器CS:IP找到程式即將執行指令的位置
1.偽指令
偽指令不對應機器碼,由編譯器進行處理
// 將名字為codesg(標號)的程式碼段跟cs暫存器聯絡起來 assume cs:codesg // XXX segment 到 XXX ends標識了一個程式碼段 codesg segment mov ax,0123H ... // 下面這兩段實現了程式返回 mov ax,4c00H int 21H codesg ends end // 彙編程式結束的標誌
將程式碼儲存為asm格式的檔案後就可以採用微軟的masm彙編編譯器來編譯彙編程式碼。(注意編譯後生成的是filename.obj還需要將其連結為可執行檔案filename.exe,連線可以使用微軟的Overlay Linker3.60聯結器)
2.[bx]和loop指令
mov ax,[bx]
功能:bx中存放的資料作為一個偏移地址EA,段地址SA預設在ds中,將SE:EA處的資料送入ax中,即(ax)=((ds)*16+(dx))
inc bx
是指bx中的內容加1
PS:用’()’來表示一個暫存器或者記憶體單元中的內容。比如(ax)就表示暫存器ax中的內容
loop指令實現迴圈公佈功能,cx中儲存了迴圈次數
assume cs:codesg codesg segment mov ax,0123H mov cx,11 // s是一個標號 // 只要cx中的值不為0,則loop都回去執行標號s出的值 s:add ax,ax loop s mov ax,4c00H int 21H codesg ends end
3.dw和end
assume cs:codesg codesg segment dw 0123h,0456h,0789h,0defh start:mov ax,0123H mov cx,11 // s是一個標號 // 只要cx中的值不為0,則loop都回去執行標號s出的值 s:add ax,ax loop s mov ax,4c00H int 21H codesg ends end start
dw
定義了多個字元型資料,每個資料佔用16個位元組的記憶體空間。取用時從cs去的段地址, dw
最先定義所以段偏移為0,之後bx加2操作進行連續取用。
end
除了通知編譯器程式結束外,還可以告訴編譯器程式的入口在什麼地方。
三、更靈活的定位記憶體地址的方法
0.七種定址方式
定址方式: 指令中指明運算元存放位置的表達方式。
定址方式可以分為:
立即數定址方式(存放在指令當中) mov AL,10H-->立即數(只能是源運算元,即暫存器或者儲存器) 暫存器定址方式(存於暫存器中) inc cx;加1 dec cs;減1 mov ax,bx 儲存器定址方式(存放於儲存器之中) | |mov ax,[25000H]-->儲存器運算元 | |->直接定址方式 | |->暫存器間接定址方式 | |->暫存器相對定址方式 | |->基址加變址定址方式 | |->相對加基址變址定址方式
1.and和or指令
;可以將操作物件的相應位設為0,其它位保持不變 and a1,11111110B ;可以將操作物件的相應位設為1,其它位保持不變 or a1,00000001B
2.ASCII
a字元–>61H儲存在指定空間中
;使用'......'指明資料是以字元的形式給出的 data segment db 'unIX' data ends ;注意:小寫字母的ASCII碼值比大寫字母的ASCII碼值大20H
3.指令處理資料的長度
;一個字單元 mov word ptr ds:[0],1 ;一個位元組單元 mov byte ptr ds:[0],1
4.偽指令dd
dd->位元組型資料
dw->字型資料
data segment ;資料為01H,在data:0處,佔1個位元組 db 1 ;資料為0001H,在data:1處,佔1個字 dw 1 ;資料為00000001H,在data:2處,佔2個位元組 dd 1 data ends
5.dup
dup配合db,dw,dd進行資料重複
;db 重複的次數 dup (重複的位元組型資料) db 3 dup (0,1,2) ;定義了9個位元組 ;相當於db 0,1,2,0,1,2,0,1,2
四、轉移指令的原理
可以修改IP,或同時修改CS和IP的指令統稱為轉移指令。
1.操作符 offset
offset
可以取得標號的偏移地址
2.jmp指令
jmp
為無條件轉移指令,可以只修改IP,也可以同時修改CS和IP
;轉到標號處執行命令,這個是 jmp short 標號 ;段間轉移 jmp far ptr 標號
3.jcxz指令
jcxz
條件轉移指令
jcxz 標號
4.loop指令
loop指令為迴圈指令
loop 標號
5.in指令
用於CPU從外設埠接收資料
6.out輸出指令
用於CPU向外設埠傳送資料
7.xchg交換指令
8.地址傳送指令:LEA & LDS & LES
;reg16--16位通用暫存器 ;mem--儲存單元 LEA reg16,mem
9.標誌傳送指令:LAHF & SAHF & PUSHF & POPF
五、算數運算指令的原理
1.加法指令
• ADD(Addition) 加法指令
• ADC(Add withCarry)帶進位加法指令
• INC(Increment)加 1指令
• AAA(ASCIIadjustforaddition)加法ASCII調整指令
• DAA(Decimaladjustforaddition)加法十進位制調整指令
2.減法指令
8086有7條減法指令:
• SUB(Subtraction)減法指令
• SBB(SubtractionwithBorrow)進位減法指令
• DEC(Decrement by 1)減1指令
• NEG(Negate) 求補指令
• CMP(Compare)比較指令
• AAS(ASCII Adjust for Subtraction) 減法ASCII調整指令
• DAS(Decimal Adjust for Subtraction) 減法十進位制調整指令
3. 乘法指令
1)無符號乘法(MUL)
2)帶符號乘法(IMUL)
4.除法指令
1)無符號除法(DIV)
2)帶符號除法(IDIV)
3)位元組擴充套件指令(CBW)
4)字擴充套件指令(CWD)
5.十進位制調整指令
共六條
• AAA非壓縮BCD碼的加法十進位制調整
• DAA壓縮BCD碼的加法十進位制調整
• AAS非壓縮BCD碼的減法十進位制調整
• DAS壓縮BCD碼的減法十進位制調整
• AAM乘法的十進位制調整
• AAD除法的十進位制調整
六、邏輯運算和移位指令
針對二進位制0/1進行的操作
1.邏輯運算指令
• AND邏輯“與”指令(有0則0)
• TEST測試指令(只改變標誌位)
• OR邏輯“或”指令(有1則1)
• XOR(exclusive OR)邏輯“異或”指令(相同為0,不同為1)
• NOT邏輯“非”指令(不能是立即數)
2.移位指令
• SAL (Shift Arithmetic Left)算術左移(無符號數乘2,最高位進CL)
• SAR (Shiftarithmeticright)算術右移(無符號數除2,最低位進CF)
• SHL (Shift logical left)邏輯左移(最低位不變,)
• SHR (Shiftlogicalright)邏輯右移(最高位不變,低位移入CF)
• ROL (Rotateleft)迴圈左移
• ROR (Rotateright)迴圈右移
• RCL (Rotateleftwith carry)帶進位迴圈左移(就是迴圈時是帶CF的)
• RCR (Rotateright withcarry)帶進位迴圈右移
七、串操作類指令
• “串”就是記憶體中一段地址相連的 位元組B或字W ;
• 串操作,也叫資料塊操作;
• 可實現儲存器資料間的直接傳送;
• 8086有5種基本串操作:
MOVS(Move string)串傳送指令
CMPS(Compare string)串比較指令
SCAS(Scan string)串掃描指令
LODS(Load from string)取串指令
STOS (Store in to string)存串指令
1.標誌處理指令
• CLC (Clearcarryflag)清C標誌
• STC(Setcarryflag )置C標誌
• CMC(Complementcarryflag)對C求反
• CLD(Cleardirectionflag)清D標誌
• STD(Setdirectionflag)置D標誌
• CLI(Clearinterruptflag)清I標誌
• STI (Setinterruptenableflag)置I標誌
2.其他處理機控制指令
• NOP(Nooperation)空操作
• HLT(Halt) CPU暫停狀態
• WAITCPU等待狀態
• ESC交權
• LOCK(Lockbus)匯流排鎖定
八、opcode
操作碼(Operation Code, OPCode) 描述機器語言指令中,指定要執行某種操作的機器碼。
OPCode在不同的場合中通常具有不同的含義,例如PHP虛擬機器(Zend VM)、java虛擬機器(JVM)
以及一些軟體保護虛擬機器中的最小操作單元都可以稱之為OPCode。