匯編語言
匯編指令 =》通過編譯器 =》010100101
偽指令 =》告訴翻譯軟件也就是編譯器,這里怎么翻譯,那里怎么翻譯,有編譯器執行,沒有對應的機器指令
符號體系 =》沒有對應的機器指令,由編譯器執行
機器指令和匯編指令的關系?
通過編譯器可以一一對應
CPU 通過指令來控制整個計算機
指令和數據
CPU 在工作時 需要對 指令和數據進行區分
指令和數據是以什么形式存放在內存中的?
以二進制形式存放在內存中的
內存也叫存儲單元
最小的存儲單位是字節
1字節(Byte) = 2個16進制數字 = 8個2進制數字
1Byte = 8bit
對字節(存儲單元)進行編號
CPU對于內存的讀寫是通過導線和內存進行傳輸數據,這些導線和平常電子元件常見
銅線一樣只是做的細罷了,這些導線在一起通常成為總線,為了區分這些總線傳輸的
容邏輯上分為3類,地址總線(傳輸的是內存地址)、控制總線(傳輸的是控制命令
)、數據總線(傳輸的是控制的數據)
ROM 只允許讀取,不允許寫入,不通電的情況下里面的數據還是保持的
RAM 運行寫入,允許讀取,電沒了就沒了
通用寄存器 一般存放數據
通用寄存器表示形式 = AX-4E20
AX = AH + AL H = high 高(前兩位) L = low 低(后兩位)
BX = BH + BL
CX = CH + CL
DX = DH + DL
寄存器是相互獨立的
AH 和 AL 是沒有關系的
move ax,bl
這一行代碼是錯的,8位寄存器不能寫到16位的寄存器中
注意寄存器能夠寫的最大值 一個字節是 255 = FF
AX = 65535 = FFFFH
表示地址信息的寄存器
左邊:段地址 右邊:偏移地址
虛擬 8086CPU 20根地址線 20bit 寄存器16位,只有16bit
位數不匹配,屬于設計失誤
補救:
物理地址 = 基礎地址 + 偏移地址
基礎地址 = 段地址 = 16(10H)
段地址 偏移地址
1238H C8H = 1230H * 10H + C8H
= 12300H + C8H = 123C8H
幫助理解的小例子
學校 體育館 圖書館 16進制
0 2000 2826
我現在有2張能寫4位數字的字條
第一張 第二張
0 + 2826
2000 + 826
我現在有2張能寫3位數字的紙條
第一張 第二張
200 + 826 = 200(段地址)*10 + 826(偏移地址) = 2826
1.CPU中存放段地址信息的寄存器? ds es ss cs
2.CPU中存放偏移地址信息的寄存器? bp ip sp si di bx(bx可以把地址信息當做數據來存儲)
3.偏移地址能夠表示的最大值是多少? FFFFH
CPU是怎么區分指令和數據的?
CPU將CS:IP所組合(指向)出來的地址里面的內容全部當做指令
指令和數據存放內存中沒有區別!!
指令是有長度的,可以由多個字節組成
指令執行的過程
1. CPU 從 cs:ip 所組合的地址中讀取指令,將這個指令存放到指令緩沖器中
2. IP = IP + 所讀指令的字節數
3. 執行指令緩存器中的內容,回到步驟1 重復這個過程
轉移指令
能夠修改ip或者cs 或者同時修改的指令
jmp 2000:0 前面的是ip,后面的是cs
jmp 寄存器 例:jmp ax 就等于把ax的地址賦值給ip
檢測點
1.下面的3條指令執行后,CPU 幾次修改了IP?都是在什么時候?最后IP中的值是多少?
move ax,bx => 指令緩存器 => 1 => 執行
sub ax,bx => 指令緩存器 => 1 => 執行
jmp ax => 指令緩存器 => 1 => 執行 => 1
答案:一共執行了4次,最后 ip = 0
call 轉移指令,相當于調用方法
call cpy_Boot : --->指令緩沖器中--->ip--->
:call
move ax,1000H :IP指向move ax,1000H 將ip保存起來-->跳轉到cpy_Boot方法里
move ax,4c00H
int 21H
:---------------
cpy_Boot:
move bx,1000H
move bx,1001H
ret :返回,跳轉回call方法保存的ip地址所指向的指令
move cx,2000H 該指令并不會被執行
匯編程序員就是通過匯編指令修改 CPU 的寄存器中的內容控制 CPU,從而達到控制整個計算機的目的
add指令加法練習
1.寫幾條指令,將一段內存中連續3個字型數據累加存放到 AX 中
20000H 12H => 3412H
20001H 34H
20002H 99H => 8899H
20003H 88H
20004H FFH => EEFFH
20005H EEH
指令代碼如下:
move bx,2000H
move ds,bx
move ax,0
add ax,ds:[0]
add ax,ds:[2]
add ax,ds:[4]
段地址:偏移地址
ss:sp
push ax => sp-2 => ax存放到ss:sp-2
pop ax => ss:sp存放到ax => sp+2
1. CS:IP 和指令有關
2. DS:[0] [1] ... 和數據有關
3. SS:SP 臨時性數據
數據在哪里
數據的長度 字節型數據 字型數據 AX BX CX DX AH AL BH BL
數據的處理 ADD SUB
數據存放到哪里
數據是我們自己安排的
存放到哪里也是自己安排
指令在哪里也要自己安排
自由的代價:謹慎
匯編語言
匯編指令
偽指令 由編譯器執行的
符號體系
1.編寫源代碼 源程序
2.編譯(通過編譯器)
3.鏈接
4.執行程序
loop 循環指令 CX = CX - 1 檢測CX是不是等于0
循環體
CX 循環次數
loop循環的執行順序是先執行代碼,然后將CX減去1,拿CX減去1的結果與0進行比較,如果不相等則跳轉到上方進行循環,如果等于0則繼續執行下方的代碼。
能夠改變 CS:IP 的是轉移指令
loop是轉移指令
move ax,0
move cx,123
addNumber: add ax,236
move dx,1000H
move dx,2000H
loop addNumber // 標號 地址
move ax,4C00H
int 21H
coder ends
end
and指令 和 or指令
and指令:邏輯運算指令,按位進行 與 運算
or指令:邏輯運算指令,按位進行 或 運算
ds:[bx+5] 偏移地址的組合
inc(a) 就相當與 a:=a+1 即在本次循環是累加
si和di 偏移地址寄存器
使用方法和bx一樣
ds:[bx]
ds:[bx+5]
start: move ax,data
move ds,ax
move es,ax
move si,0
move di,16 //數據從哪里來 ds:[si] 數據到哪里去 es:[di]
move cx,8
copyData: move dx,ds:[si]
move es:[di],dx
add si,2
add di,2
loop copyData
/* 第二種解決辦法
start: move ax,stack
move ss,ax
move sp,32
move ax,data
move ds,ax
move es,ax
move si,0
move di,16 //數據從哪里來 ds:[si] 數據到哪里去 es:[di]
move cx,8
copyData: push ds:[si]
pop es:[di]
add si,2
add di,2
loop copyData
*/
內存訪問形式
ds:[bx+si]
ds:[bx+di]
ds:[bx+si+4]
ds:[bx+di+5]
ds:[?] ds為段地址 []里面的值為偏移地址
一個字型數據占兩個字節 一個字節8位
歸納1:數據可以存放在哪?
1.CPU的寄存器中
ax,bx,cx,dx ah,al bh,bl ch,cl dh,dl
2.內存中
地址信息 8086CPU
段地址信息:偏移地址信息
ds ip
es sp
ss si
cs di
bp
ds:[0] ds:[bx] ds:[si] ds:[di] ds:[bp]
//ds:[si+di] si+di是不允許這么寫的
ds:[bx+si+2] ds:[bx+di] ds:[bx+si]
ss:[bp+si+2]
3.端口中
歸納2:數據的長度
字型數據 字節型數據
mov ax,1 move al,1
move bx,ds:[0] move al,bl
move ax,ds
move ax,1000
move ds,ax
inc ax
把數據當做字型數據存放到ds中 把數據當做字型數據存放到ds中
mov word ptr ds:[0],1 mov byte ptr ds:[0],222
inc word ptr ds:[bx] inc byte ptr ds:[0]
除數 8bit 16bit 存在內存單元中 或者 寄存器中
被除數 AX或者 AX和BX中
如果除數為8bit,被除數則為16bit,存放在AX中
如果除數為16bit,被除數則為32bit,AX存放低16bit,DX存放高16bit
結果:如果除數為8bit,則AL 存放 商,AH 存放余數
如果除數為16bit,則AX 存放 商,DX 存放余數
db 占1個字節
dw 占2個字節
dd 占4個字節
inc bx 將bx中的值加1
dec bx 將bx中的值減去1
轉移指令
靈活性
標號處的地址 - jmp指令后的第一個字節的地址 = 位移 ;編譯器
jmp 段間轉移
短轉移 -128 ~ 127
DFFFSET 偽指令
條件轉移指令
jcxz 標號 j = jmp cx 寄存器 z = zero
if cx 等于 0 jmp 標號
nop 指令 ;CPU 什么事都不做 只是占用兩個字節
ret pop ip ss:sp 字型數據 => ip sp+2
retf pop ip pop cs
jmp 位移
call 指令比jmp多做了一件事 push ip push的是第2步時已經 自加所讀指令字節數 的ip
call s 與 ret 配合使用 call:push ip ret:pop ip
call far ptr s 與 retf 配合使用
call far ptr:push cs, push ip retf:pop ip pop cs
mul 乘法
8bit 一個字節 al bl mul byte ptr ds:[0] AX
16bit 2個字節 ax bx mul word ptr ds:[0] AX DX
標志位寄存器
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
OF DF IF TF SF ZF AF PF CF
運算溢出,溢出的1是存在 CF 中
CF: Carry Flag
ZF: Zero Flag
PF: Parity Flag
SF: Sign Flag
標志 真值為1 假值為0
OF OV NV Overflow not Overflow
SF NG PL NG = negative 負數 PL = positive 正數
ZF ZR NZ ZR = Zero NZ = not Zero
PF PE PO PE = Even 偶數 PO = odd 奇數
CF CY NC CY = Carry Yes(進位) NC= notCarry
DF DN UP DN = Down
mul、div 乘法、除法指令不影響標志位
CF 是把結果都當做無符號運算
OF 是有符號運算
adc指令 add carry
add ax,bx ax = ax + bx + carry
sbb sub carry
cmp指令
sub ax,bx ax = ax - bx
cmp ax,bx 只執行 ax-bx 這個過程,不保存結果至ax中,但是會修改標志位
je equal
jne not equal
jb below
jnb not below
ja above
jna not above
內中斷
中斷:發生了需要CPU立刻去處理的信息
1.除法錯誤 divide overflow
2.單步執行 debug
3.執行into指令
4.執行int指令
中斷信息 需要一個程序去處理
CS,IP => 需要處理的程序入口 段地址,偏移地址
中斷向量表 中斷類型碼
0號處理中斷信息的程序地址 CS:IP
1號處理中斷信息的程序地址 CS:IP
2號處理中斷信息的程序地址 CS:IP
0000:0000 - 0000:03FF
段地址:N*4+2 偏移地址:N*4
中斷過程
1.取得中斷類型碼
2.保存標志寄存器 => 棧 pushf
3.將標志寄存器的第8 TF 和 第9位 IF 設置為0
4.push cs
5.push ip
6.cs = N*4+2 ip = N*4
中斷處理程序返回的辦法
//ss:sp ip cs pushf
iret // 一條程序等于下面三條程序的效果
pop ip
pop cs
popf
int 指令
1.取中斷類型碼N
2.標志位寄存器入棧 IF = 0 TF = 0
3.push cs push ip
4.cs = N*4+2 ip = N*4
BIOS 和 DOS 所提供的中斷的例程 = 中斷程序
BIOS 系統登記在中斷向量表里的
ROM內存只允許讀取 不允許寫入的 固化在內存中
BIOS Basic Input output System
1.硬件系統的檢測和初始化程序
2.將外部中斷和內部中斷程序登記在 中斷向量表中
3.用于對硬件設備進行 I/O 操作的中斷程序 放到中斷向量表中
4.其他相關于硬件系統的 中斷程序
電腦開機
CS = FFFF IP = 0
1.硬件系統的檢測和初始化程序
2.將中斷程序的 CS 和 IP 直接登記在中斷向量表中
3.調用 into9H 進行操作的系統引導,將計算機交給操作系統控制 DOS
4.DOS 系統將相應的 中斷程序入口地址 存到中斷向量表中 包括程序
shl 左移指令
1.將一個寄存器 或者內存單元 中的數據向左移位 bit位
2.將移除的這一位 放到 CF 中
3.最低位用 0 補充
shr 右移指令
用int 13H 中斷程序,對磁盤進行讀寫 ;BIOS
軟盤 C盤 0面0道1扇 ;start system
上下兩面
一面 = 80磁道
-磁道 = 18扇區
-扇區 = 512字節
2 * 80 * 18 * 512 = 1440KB 1.44M
面號 從0開始
磁道 從0開始
扇區 從1開始
匯編語言
最后編輯于 :
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
- 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
- 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
- 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
推薦閱讀更多精彩內容
- 文章也同時在個人博客 http://kimihe.com/更新 引言 本章介紹匯編語言程序的創建過程,我們要準備踏...
- 原文鏈接 https://azeria-labs.com/writing-arm-assembly-part-1/...
- 經典匯編語言教程:匯編語言程序設計 經典匯編語言教程·相關目錄第1章 匯編語言的由來,數據類型第2章 CPU資源和...
- 匯編語言編輯、匯編、連接、運行的全過程 assume cs : xxxxxx segment mov ax, 2a...