通過編寫乙個分解整數並顯示的乙個程式,來學習一些彙編的基礎指令和語法
處理器在加電或者復位以後,如果硬碟是首選的啟動裝置,那麼rom-bios將試圖讀取硬碟的0面0道1扇區。這就是主引導扇區,會先把主引導扇區的**(指令集)載入到記憶體,然後處理器來執行,一般主引導扇區是用來啟動作業系統的。但此次,我們把編寫的程式載入到主引導扇區,讓它被處理器執行。
為了顯示文字,主要是依靠顯示器和顯示卡,顯示卡裡面有乙個儲存器,通常稱為視訊記憶體。視訊記憶體是用來告訴顯示器應該顯示什麼字元。顯示器的最小單位是畫素。
一開始想的是將視訊記憶體裡面的二進位制數和畫素對應起來,比如1對應亮,0對應不亮(也就是黑),但這只能黑白形式,現在都是彩色的了,所以就用到了3個位元組來表示顏色。
另乙個問題是,將二進位制數和畫素一 一 對應起來,是很麻煩的,這裡引入了ascii碼,我們不需要想視訊記憶體裡面存的數怎麼和畫素聯絡起來,只需要在視訊記憶體裡面寫入這個字元的ascii碼,就可以在螢幕上顯示出來了(這中間的一些技術細節,就是字元發生器和控制電路的事情了)
我們知道,視訊記憶體是在顯示卡上面的,處理器需要訪問顯示卡,才能讓字元顯示出來,這個過程有點麻煩了,效率不高,所以想到直接讓視訊記憶體對映到記憶體裡面,記憶體裡面專門劃出一片空間來和視訊記憶體對映。一般0xb8000-0xbffff這段物理空間是留給顯示卡的。
直接用暫存器來儲存分解的數顯然是不太好的,乙個是暫存器的數量有限,另乙個是暫存器還有它別的任務得做,所以想到直接在記憶體裡面開闢出一段連續的空間,這些空間來放被分解的數。
很簡單,因為0x8000-0xbffff是和視訊記憶體形成對映的,直接把那些分解的數用mov指令移到那片記憶體位址就ok了。
1 ;**清單5-1「;」代表注釋符
2 ;檔名:c05_mbr.asm
3 ;檔案說明:硬碟主引導扇區**
4 ;建立日期:2011-3-31 21:15
56 mov ax,0xb800
7 mov es,ax
6.7行執行後,es段暫存器指向了記憶體位址0xb800,也就是用來顯示字元的那一片位址區域
89 ;以下顯示字串"label offset:"
10 mov byte [es:0x00],『l』這裡的』l』也可以換成對應的ascii 0x4c;[ ]代表是記憶體位址
11 mov byte [es:0x01],0x07
12 mov byte [es:0x02],『a』
13 mov byte [es:0x03],0x07
14 mov byte [es:0x04],『b』
15 mov byte [es:0x05],0x07
16 mov byte [es:0x06],『e』
17 mov byte [es:0x07],0x07
18 mov byte [es:0x08],『l』
19 mov byte [es:0x09],0x07
20 mov byte [es:0x0a],』 』
21 mov byte [es:0x0b],0x07
22 mov byte [es:0x0c],「o」
23 mov byte [es:0x0d],0x07
24 mov byte [es:0x0e],『f』
25 mov byte [es:0x0f],0x07
26 mov byte [es:0x10],『f』
27 mov byte [es:0x11],0x07
28 mov byte [es:0x12],『s』
29 mov byte [es:0x13],0x07
30 mov byte [es:0x14],『e』
31 mov byte [es:0x15],0x07
32 mov byte [es:0x16],『t』
33 mov byte [es:0x17],0x07
34 mov byte [es:0x18],』:』
35 mov byte [es:0x19],0x07
3637 mov ax,number;取得標號number的彙編位址(也可以說偏移位址)
38 mov bx,10;因為分解數要不斷除以10,這裡10放到了bx暫存器裡面作除數用的
3940;設定資料段的基位址
41 mov cx,cs;41.42作用是讓資料段暫存器和**段暫存器指向同乙個段位址
42 mov ds,cx
4344;求個位上的數字
45 mov dx,0
46 div bx
47 mov [0x7c00+number+0x00],dl;儲存個位上的數字,主引導扇區的**是從0x7c00開始載入的,所以需要加上。
4849 ;求十位上的數字
50 xor dx,dx;這裡直接把dx,dx歸0了,因為是異或運算,而且效率要比mov dx ,0高
51 div bx
52 mov [0x7c00+number+0x01],dl ;儲存十位上的數字
5354 ;求百位上的數字
55 xor dx,dx
56 div bx
57 mov [0x7c00+number+0x02],dl;儲存百位上的數字
5859 ;求千位上的數字
60 xor dx,dx
61 div bx
62 mov [0x7c00+number+0x03],dl ;儲存千位上的數字
6364 ;求萬位上的數字
65 xor dx,dx
66 div bx
67 mov [0x7c00+number+0x04],dl ;儲存萬位上的數字
6869;以下用十進位制顯示標號的偏移位址
70 mov al,[0x7c00+number+0x04]
71 add al,0x30
72 mov [es:0x1a],al
73 mov byte [es:0x1b],0x04
7475 mov al,[0x7c00+number+0x03]
76 add al,0x30
77 mov [es:0x1c],al
78 mov byte [es:0x1d],0x04
7980 mov al,[0x7c00+number+0x02]
81 add al,0x30
82 mov [es:0x1e],al
83 mov byte [es:0x1f],0x04
8485 mov al,[0x7c00+number+0x01]
86 add al,0x30
87 mov [es:0x20],al
88 mov byte [es:0x21],0x04
8990 mov al,[0x7c00+number+0x00]
91 add al,0x30
92 mov [es:0x22],al
93 mov byte [es:0x23],0x04
9495 mov byte [es:0x24],『d』
96 mov byte [es:0x25],0x07
9798 infi: jmp near infi ;無限迴圈
99100 number db 0,0,0,0,0;db是乙個偽指令,不會被編譯成機器碼,用來宣告,這裡相當於開闢了5個位元組的記憶體空間,然後都初始化為0了方便儲存分解之後的數字。然後number是乙個標號,可以代表該處的彙編位址,一般被用來引用
101102 times 203 db 0;重複執行203次db 0 命令,相當於開闢了連續的203位元組的記憶體空間且置於0
103 db 0x55,0xaa;保證主引導扇區的結尾格式
mov指令用於資料傳送
1.mov指令的目的運算元不能是立即數
2.目的運算元和源運算元不允許同時為記憶體單元
3.目的運算元必須是通用暫存器或者記憶體單元
傳送指令只影響目的運算元的內容,不改變源運算元的內容
比如 mov ah,bh 指令執行後,ah和bh的內容相同
div是除法指令
第一種型別是 16位的二進位制數除以8位二進位制數
這種情況下,被除數必須在暫存器ax中,必須事先傳到ax裡,除數可以由8位通用暫存器或者記憶體單元提供。指令執行後,商在暫存器al中,餘數在ah中
第二種型別是用32位的二進位制數除以16位的二進位制數,因為16位暫存器只能放16位的,所以要拆開放,高16位放在dx中,低16位放在ax中,除數可以由16位通用暫存器或者記憶體單元提供,指令執行 後,商在ax中,餘數在dx中
一般是編譯時,編譯器生成的位址,每個指令都對應乙個,是從0開始的,第乙個指令對應的彙編位址是0
標號可以代表該指令處對應的彙編位址,一般是在匯程式設計序裡面被引用的。
像db dw 這些都是偽指令,也就是說不能被編譯成機器碼的,編譯完成後,自動消失,只在編譯時起作用。
db是用來宣告的,db是宣告位元組,跟在後面的數都佔乙個位元組。
dw是宣告字資料
dd是宣告雙字資料
dq是宣告四字資料
彙編學習 2
1.輸入乙個無符號數,統計 0 的個數 unsigned int a int count printf 輸入乙個無符號整數 scanf u a asm2.輸入兩個字元 a7a6 a1a0和b7b6 b1b0 合併為16位無符號整數 a7b7a6b6 a1b1a0b0 char a,b unsigne...
彙編學習(2)
我們希望像顯示器輸出一段資訊,那麼必須將這段資訊寫到視訊記憶體中,顯示卡才能將它輸出到顯示器上。要向視訊記憶體中寫入資料,必須知道顯存在記憶體位址空間中的位址。從圖中可以看出,從位址0 9ffff的記憶體單元中讀取資料,實際上就是在讀取主隨機儲存器中的資料 向位址a0000 bffff的記憶體單元中...
彙編學習記錄2
組合語言的思路 函式的工作原理 1 常用指令 為了照顧到沒學過匯程式設計序的同志們,這裡簡單介紹一下常見的幾種彙編指令。a add 加法指令,第乙個是目標運算元,第二個是源運算元,格式為 目標運算元 目標運算元 源運算元 b sub 減法指令,格式同 add c call 呼叫函式,一般函式的引數放...