匯程式設計序基礎知識要點:
匯程式設計序由彙編指令、偽指令、標號組成
彙編指令是cpu真正要執行的**
偽指令不是用於被cpu執行的**,而是用於被編譯器識別的特殊指令,比如end告訴編譯器匯程式設計序到此為止,start告訴編譯器程式的第一條
指令從這裡開始
標號實際上是位址的一種表示,表明了某乙個段的起始位址
80x86cpu通用暫存器:ax,bx,cx,dx
段暫存器:ds,cs,ss,es
特殊暫存器:ip,sp
其他的暫存器:si,di,bp,標誌位暫存器
word型別資料存放在記憶體中時,高位存放在高位元組,地位存放在低位元組
如:1234h
2000:34h
2001:12h
bx中預設存放資料段偏移位址
bp和bx類似,但是bp的預設段位址在ss中
ds中預設存放記憶體基位址
cs中存放cpu執行的機器指令的段位址
ip中存放cpu執行的機器指令的偏移位址
ss中存放程式的棧基位址
sp中存放棧頂的偏移位址
cx中存放loop迴圈的次數
ax是add運算的預設結果存放位址
si和di是和bx相似的暫存器,他們都預設存放資料段的偏移位址,
但是si和di不能被分成兩個位元組的暫存器使用
注意點:
[bx+100]可以寫成:100[bx] 或 [100+bx] 或 [bx].200
[bx+si]可以寫成:[bx][si]
[bx+si+idata] idata[bx+si] idata[bx][si] [bx+si].idata [bx][si].idata
在80x86cpu中只有四個暫存器可以用於如[..]的記憶體定址,它們是bx,si,di,bp
在[..]中只有四種組合是合法的分別是:[bx+si],[bx+di],[bp+si],[bp+di]
80x86cpu可以處理兩種尺寸的資料,分別是byte和word,在彙編指令中需要指明要處理的資料是byte還是word。通常的方法是:
1.通過指令中的暫存器來表明,比如:mov ax,[bx+0]
mov al,[bp+2]
2.如果指令中沒有暫存器,或暫存器無法表明當前要操作的資料的長度型別,需要用
x ptr來標明資料的長度,這裡的x指byte 或 word
如:inc byte ptr [bx]
mov word ptr [bx], 1000h
3.有些指令預設了訪問的資料型別,比如push指令只能訪問word型別資料
轉移指令分為:段內轉移指令、段間轉移指令
段內轉移指令又分為:段內短轉移、段內近轉移
jmp 暫存器:略 段內轉移
jmp 記憶體單元:
jmp dword ptr [bx] 段間轉移
jmp word ptr [bp] 段內轉移
loop迴圈指令是跳轉指令,並且是段內短轉移指令
所有的有條件轉移指令都是段內段轉移指令,比如jcxz有條件轉移指令,含義是:
如果cx==0則跳轉到標號處,那麼跳轉的偏移量(或者說距離)是:
標號的位址-jcxz指令的下一條指令位址
ret是轉移指令,他可以實現段內近轉移和段間轉移,它的實現原理是:
從棧中彈出ip 或ip和cs,注意當實現段間轉移時,先從棧中彈出的是ip然後cs
call是轉移指令,它不能實現短轉移它的實現原理:
將當前ip或ip和cs壓入棧中,再執行跳轉到標號處的操作
cpu的標誌暫存器:
進製是指無符號數運算時最高位進製或借位
溢位是指有符號數的運算中產生無法表達的情況
指令部分:
div ***
div除法操作的被除數預設放在ax或dx和ax中。
當除數是8位時,被除數是16位,被除數放在ax中,運算的結果存放在al中,餘數存放在ah中。
當除數是16位時,被除數是32位,被除數放在dx和ax中,其中dx中存放的是被除數的高16位,ax中存放的是被除數的低16位
而運算的結果存放在ax中,餘數存放在dx中
adc和sbb都是帶cf的運算操作,之所以使用這種帶進製的運算操作,主要是為了解決大數的加減法操作。
如:假設使用的cpu是8086 8088 80286,那麼cpu中只有16位的暫存器,當處理16位的加減法運算時直接
將運算元放置於乙個暫存器中即可,當處理32位的加減法時可以用乙個暫存器放置32位的低16位(ax),
用另乙個暫存器放置32位的高16位(dx),但是當低16位的相加減出現進製或借位時,如果沒有adc或
sbb我們需要如下來處理:
add ax, [bx] ;ax和[bx]中存放低16位
add dx, [bx+2] ;dx和[bx+2]中存放高16位
add dx, cf ;當然這裡要取得cf需要進一步處理
如果使用了adc,則可以取消上面的第三步
add ax, [bx]
adc dx, [bx+2]
同樣的,但處理減法操作時,遇到借位不用sbb時,需要我們對高16的操作結果減去cf
db dw dd都是偽指令,分別是定義byte, word, double world
dup 重複次數 (重複的資料)
cmp指令實際上就是做了減法操作,但是操作的結果並沒有儲存在cpu或記憶體中。
cmp指令雖然不會將操作的結果放在任何地方,但是cmp的結果會影響標誌暫存器。
比如:比較兩個無符號數 cmp ax, bx
如果ax < bx 則標誌暫存器的zf=0 cf=1
cmp不僅可以比較無符號數,還可以比較有符號數,但比較有符號數時
sf 和 of 的值要特別注意:
sf=1並不表示ax < bx因為可能在作減法操作的時候發生了溢位的情況,這時
說明真正的操作結果應該是ax-bx>0,由於發生了溢位的情況所以才導致結果為負。
所以對有符號數的比較時要特別注意of的值
sf=0, of=0 沒有溢位,所以減法的操作結果是正確的,說明ax>bx
sf=0, of=1 有溢位,所以減法的操作結果是錯誤的,結果應該是負的,axbx
je:jump if equal zf=1
jne:jump if not equal zf=0
ja:jump if above cf=0且zf=0
jna:jump if not above cf=1或zf=0
jb:jump if below cf=1
jnb:jump if not below cf=0
movsb/movsw是串傳送操作
es:di指向目的位址
ds:si指向源位址
df標誌位表示了傳送的方向:即傳送一次之後,di和si是+還是-
如果df=0則是+ 如果df=1則是-
cld和std專門用於設定df標誌位,cld將df設為0,std將df設為1
通常movsb或movsw與rep聯合使用
rep的作用相當於loop
如:rep movsb
pushf:是將標誌位暫存器壓入棧中
popf:是將彈出標誌位暫存器
其他:shl eax, n 邏輯左移
shr eax, n邏輯右移
org 07c00將**載入到7c00處
匯程式設計序最基礎知識記錄
section text global main main mov eax,4 mov ebx,1 mov ecx,msg mov edx,len int 80h mov eax,1 int 80h msg db hello world 0xa,it s too long n r n t 0,123...
匯程式設計序 退出
作為第乙個匯程式設計序,本程式除了退出以外,並沒有執行其他的功能。目的 退出並向linux核心返回乙個狀態碼的簡單程式 輸入 無 輸出 返回乙個狀態碼.在執行程式後可通過輸入echo 來讀取狀態碼 變數 eax儲存系統呼叫號 ebx儲存返回狀態 section data section text g...
微機匯程式設計序
又是自學的一學期,呵呵。學到最後也就知道零星半點指令吧,複雜的程式可能還是不怎麼會寫,熟練當然也不敵c了,但是彙編之於嵌入式,往上走肯定少不了遇到,學好還是必要的!此次僅作入門吧。今日所學,明日之用。1 統計正負零的個數 datas segment array db 1,2,1,0,2,0,2,4,...