匯程式設計序基礎知識要點

2021-04-28 02:54:49 字數 3785 閱讀 5984

匯程式設計序基礎知識要點:

匯程式設計序由彙編指令、偽指令、標號組成

彙編指令是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,...