匯編指令
-
匯編有兩類(lèi)指令組成
- 匯編指令
如move,add,sub等,有對(duì)應(yīng)的機(jī)器指令,可以被編譯為機(jī)器指令最終被CPU執(zhí)行 - 偽指令
如assume,segment,ends,end等。沒(méi)有對(duì)應(yīng)的機(jī)器指令,由編譯器解析,最終不被CPU執(zhí)行
- 匯編指令
注釋以分號(hào)(;)開(kāi)頭
偽指令
- segment和ends的作用是定義一個(gè)段,segment代表一個(gè)段的開(kāi)始,ends代表一個(gè)段的結(jié)束
- 一個(gè)有意義的匯編程序中,至少要有一個(gè)段作為代碼段存放代碼
- assume:將用作代碼段的code段和CPU中的cs寄存器關(guān)聯(lián)起來(lái)
- end:編譯器遇到end時(shí),就結(jié)束對(duì)源程序的編譯
- 退出程序:
- mov ah,4ch
- int 21h
中斷
由軟件或者硬件發(fā)出信號(hào),使CPU暫停當(dāng)前的任務(wù),轉(zhuǎn)而去執(zhí)行另一個(gè)段子程序
中斷的分類(lèi)
硬中斷(外中斷),由外部設(shè)備(比如網(wǎng)卡、硬盤(pán))隨機(jī)引發(fā)的,比如當(dāng)網(wǎng)卡收到數(shù)據(jù)包的時(shí)候,就會(huì)發(fā)出一個(gè)中斷
-
軟中斷(內(nèi)中斷),由執(zhí)行中斷指令產(chǎn)生的,可以通過(guò)程序控制觸發(fā)
從本質(zhì)上來(lái)講,中斷是一種電信號(hào),當(dāng)設(shè)備有某種事件發(fā)生時(shí),它就會(huì)產(chǎn)生中斷,通過(guò)總線(xiàn)把電信號(hào)發(fā)送給中斷控制器。如果中斷的線(xiàn)是激活的,中斷控制器就把電信號(hào)發(fā)送給處理器的某個(gè)特定引腳。處理器于是立即停止自己正在做的事,跳到中斷處理程序的入口點(diǎn),進(jìn)行中斷處理 -
可以通過(guò)指令int n產(chǎn)生中斷
- n是中斷碼,內(nèi)存中有一張中斷向量表,用來(lái)存放中斷碼對(duì)應(yīng)中斷處理程序的入口地址
- CPU在收到中斷信號(hào)后,暫停當(dāng)前執(zhí)行的程序,跳轉(zhuǎn)到中斷碼對(duì)應(yīng)的中斷向量表地質(zhì)處,去執(zhí)行中斷處理程序
*常見(jiàn)中斷 - int 10h用于執(zhí)行BIOS中斷
- int 3是“斷點(diǎn)中斷”,用于調(diào)試程序
- int 21h用于執(zhí)行DOS系統(tǒng)功能調(diào)用,AH寄存器存儲(chǔ)功能號(hào)
DOS系統(tǒng)功能調(diào)用
- DOS系統(tǒng)功能調(diào)用
- 由DOS提供的一組實(shí)現(xiàn)特殊功能的子程序供程序員在編寫(xiě)自己的程序時(shí)調(diào)用,以減輕編程的工作量
- 涉及屏幕顯示、文件管理、I/O管理等等
- 每個(gè)子程序都有一個(gè)功能號(hào),所有的功能調(diào)用的格式都是一致的。調(diào)用的步驟大致如下:
- 系統(tǒng)功能號(hào)送到寄存器AH中;
- 入口參數(shù)送到指定的寄存器中;
- 用INT 21H指令執(zhí)行功能調(diào)用;
- 根據(jù)出口參數(shù)分析功能調(diào)用執(zhí)行情況。
這是一段完整的匯編代碼
將數(shù)據(jù)存放在ds中,并將ds中的數(shù)據(jù)以字節(jié)的形式倒敘存入棧中
assume cs:code
code segment
mov ax,2000h
mov ds,ax
mov [0],1122h
mov [2],3344h
mov [4],5566h
mov [6],7788h
mov [8],99aah
mov ax,3000h
mov ss,ax
mov sp,ah
push [8]
push [6]
push [4]
push [2]
push [0]
mov ah,4ch
int 21h
code ends
end
loop指令
- loop指令和cx寄存器配合使用,用于循環(huán)操作,類(lèi)似高級(jí)語(yǔ)言的do:while
- 使用格式
mov cx,循環(huán)次數(shù)
標(biāo)號(hào):
循環(huán)執(zhí)行的程序代碼
loop 標(biāo)號(hào)
- 每執(zhí)行一次loop 標(biāo)號(hào) cx中的值減一,如果cx-1不等于0,跳轉(zhuǎn)到標(biāo)號(hào)位置繼續(xù)執(zhí)行,否則執(zhí)行l(wèi)oop指令后面的指令
- loop $ 一直執(zhí)行這一句loop,直到cx=0,用來(lái)延時(shí)
示例1可以改寫(xiě)為
assume cs:code
code segment
mov ax,2000h
mov ds,ax
mov bx,1122h
mov cx,5;循環(huán)次數(shù)
mov si,0h;si:源變址寄存器可用來(lái)存放相對(duì)于DS段之源變址指針
s: mov [si],bx;因?yàn)閇]中不能存放數(shù)據(jù)寄存器、段寄存器和控制寄存器
add bx,2222h
add si,2
loop s;每次執(zhí)行先讓cx-1,然后判斷cx是否為0
mov ax,3000h
mov ss,ax
mov sp,0ah;這里需要sp指向10處,不能直接寫(xiě)ah
mov si,8h
p: push [si]
sub si,2
loop p
mov ah,4ch
int 21h
code ends
end
代碼分段
assume cs:code,ds:data,ss:stack
data segment
db 20 dup(0)
data ends
stack segment
db 20 dup(0)
age dw 20h;age標(biāo)號(hào) 編譯器會(huì)將其轉(zhuǎn)成地址值
stack ends
code segment
;配置ds,ss如果不配置,data,stack里面也沒(méi)數(shù)據(jù)的話(huà)三個(gè)段地址隨機(jī)并相同
;data,stack里面有數(shù)據(jù)的話(huà)會(huì)隨機(jī)分配地址,三個(gè)段地址不相同
;如果配置
mov ax,2000h
mov ds,ax
mov ax,3000h
mov ss,ax
; mov sp,14h;不用指定sp,因?yàn)樯厦鎠tack已經(jīng)指定棧段和大小了
mov [0],1122h
mov age,1122h;age物理內(nèi)存地址
push 1122h
mov ah,4ch
int 21h
code ends
end
練習(xí)
;0x00010h 11h
;0x00011h 22h
;0x00012h 33h
;求三個(gè)字節(jié)的和
; mov ax,0001h
; mov ds,ax
; mov [0],11h
; mov [1],22h
; mov [2],33h
; mov al,[0]
; add al,[1]
; add al,[2]
如果上面代碼中數(shù)據(jù)段保存的值是0xff,0xff,0xff,使用上面的計(jì)算方法,會(huì)造成溢出
assume cs:code
code segment
start:
;0x00010h ffh
;0x00011h ffh
;0x00012h ffh
;求三個(gè)字節(jié)的和
;這種情況下在使用代碼1的方式,在相加的過(guò)程中,al溢出
mov ax,0001h
mov ds,ax
mov [0],0xff;寫(xiě)ffh會(huì)報(bào)錯(cuò),無(wú)法識(shí)別這個(gè)十六進(jìn)制
mov [1],0xff
mov [2],0xff
mov bx,0h
mov al,[0]
mov ah,0h
add bx,ax
mov al,[1]
mov ah,0h
add bx,ax
mov al,[2]
mov ah,0h
add bx,ax
mov ah,4ch
int 21h
code ends
end start
使用loop指令
assume cs:code
code segment
start:
;0x00010h ffh
;0x00011h ffh
;0x00012h ffh
;求三個(gè)字節(jié)的和
;這種情況下在使用代碼1的方式,在相加的過(guò)程中,al溢出
mov ax,0001h
mov ds,ax
mov [0],0xff;寫(xiě)ffh會(huì)報(bào)錯(cuò),無(wú)法識(shí)別這個(gè)十六進(jìn)制
mov [1],0xff
mov [2],0xff
mov bx,0h
mov dx,0h
mov cx,3h
s: mov al,[bx];如果這里換成dx報(bào)語(yǔ)法錯(cuò)誤
mov ah,0h
add dx,ax
add bx,1
loop s
mov ah,4ch
int 21h
code ends
end start