匯編入門學(xué)習(xí)筆記 (十二)—— int指令、端口
參考: 《匯編語言》 王爽 第13、14章
一、int指令
1. int指令引發(fā)的中斷
int n指令,相當(dāng)于引發(fā)一個(gè)n號(hào)中斷。
執(zhí)行過程相當(dāng)于:
(1)取中斷類型嗎n。
(2)標(biāo)志寄存器入棧;設(shè)置IF=0,TF=0。
(3)CS,IP入棧
(4)(IP)=(n*4),(CS)=(n*4+2)
例子1:編寫、安裝中斷7ch,實(shí)現(xiàn)求一個(gè)word型數(shù)據(jù)的平方,用ax存放這個(gè)數(shù)據(jù)。
assume cs:code code segment start: mov ax,cs mov ds,ax mov si,offset sqr mov ax,0 mov es,ax mov di,200h mov cx,offset sqrend - offset sqr cld rep movsb mov ax,0 mov es,ax mov word ptr es:[7ch*4],200h mov word ptr es:[7ch*4+2],0 mov ax,4c00h int 21h sqr: mul ax iretsqrend: nop code ends end start
assume cs:codecode segmentstart: mov ax,3 int 7ch mov ax,4c00h int 21hcode endsend start
例子2:編寫、安裝7ch中斷,實(shí)現(xiàn)將data段中的字符串轉(zhuǎn)化為大寫。
assume cs:codecode segmentstart: mov ax,cs mov ds,ax mov si,offset change mov ax,0 mov es,ax mov di,200h mov cx,offset changeend - offset change cld rep movsb mov ax,0 mov es,ax mov word ptr es:[7ch*4],200h mov word ptr es:[7ch*4+2],0 mov ax,4c00h int 21hchange: push cx push sis: mov ch,0 mov cl,ds:[si] jcxz ok and cl,11011111b mov ds:[si],cl inc si jmp short sok: pop si pop cx iretchangeend: nop code endsend start
assume cs:codedata segment db conversation,0data endscode segmentstart: mov ax,data mov ds,ax mov si,0 int 7ch mov ax,4c00h int 21h code endsend start
例子3:使中斷7ch實(shí)現(xiàn)loop指令的功能。
assume cs:codecode segmentstart: mov ax,cs mov ds,ax mov si,offset lp mov ax,0 mov es,ax mov di,200h mov cx,offset lpend - offset lp cld rep movsb mov ax,0 mov es,ax mov word ptr es:[7ch*4],200h mov word ptr es:[7ch*4+2],0 mov ax,4c00h int 21hlp: push bp mov bp,sp dec cx jcxz lpret add [bp+2],bxlpret: pop bp iretlpend: nop code endsend start
assume cs:codecode segmentstart: mov ax,0b800h mov es,ax mov di,160*12 mov bx,offset s - offset se mov cx,80s: mov byte ptr es:[di],! add di,2 int 7chse: nop mov ax,4c00h int 21hcode endsend start
2. BIOS和DOS的中斷例程
BIOS中主要包含:
(1)硬件系統(tǒng)的檢測和初始化程序
(2)外部中斷和內(nèi)部中斷的中斷例程
(3)用于對(duì)硬件設(shè)備進(jìn)行I/O操作的中斷例程
(4)其他和硬件系統(tǒng)相關(guān)的中斷例程
BIOS和DOS提供的中斷例程安裝過程
(1)開機(jī),初始化CS=0FFFFH,IP=0,執(zhí)行FFFF:0程序。FFFF:0程序有一條跳轉(zhuǎn)指令,執(zhí)行完后,CPU會(huì)去執(zhí)行BIOS中的硬件系統(tǒng)檢測和初始化程序。
(2)初始化程序?qū)⒔IOS所支持的中斷向量,即將BIOS中提供的中斷例程的入口地址登記在中斷向量表中。注意:BIOS所提供的中斷例程,只需要將入口地址登記在中斷向量表中即可,因?yàn)樗鼈兪枪袒赗OM中的。
(3)硬件系統(tǒng)檢測和初始化完成后,調(diào)用int 19h進(jìn)行操作系統(tǒng)的引導(dǎo)。從此將計(jì)算機(jī)交給操作系統(tǒng)控制
(4)DOS啟動(dòng)后,除了完成其他工作外,還將他所提供的中斷例程裝入內(nèi)存中,并建立相應(yīng)的中斷向量。
一般來說,一個(gè)中斷例程包含了多個(gè)子程序,用ah來傳遞內(nèi)部子程序的編號(hào)
int 10h中斷
它是BIOS提供的中斷例程,其中包含了多個(gè)和屏幕輸出有關(guān)的子程序
ah=2 設(shè)置光標(biāo)位置,此時(shí)bh存放 第幾頁;dh存放行號(hào);dl存放列號(hào)
ah=9 在光標(biāo)位置顯示字符,此時(shí)al存放字符;bl存放顏色屬性;bh存放第幾頁;cx存放這個(gè)字符重復(fù)顯示幾
例子:
assume cs:codecode segmentstart: mov ah,2 mov bh,0 mov dh,5 mov dl,12 int 10h mov ah,9 mov al,a mov bl,11001010b mov bh,0 mov cx,3 int 10h mov ax,4c00h int 21hcode endsend start
int 21h中斷
它是DOS提供的中斷例程,包含了DOS提供給程序員在編程時(shí)調(diào)用的子程序。
前面我們一直用下面的代碼返回
mov ax,4c00hint 21h
其實(shí)這是用了21號(hào)中斷例程的4ch號(hào)子程序,al是用來存放程序返回值的,上面的代碼即0
本質(zhì)就是:
mov ah,4chmov al,0int 21h
21h號(hào)中斷例程的9號(hào)子程序功能是在光標(biāo)位置顯示字符串,用ds:dx指定字符串的首地址,字符串要以‘$’結(jié)尾
例子:
assume cs:codedata segment db Welcome to masm!,$data endscode segmentstart: mov ah,2 mov bh,0 mov dh,5 mov dl,12 int 10h mov ax,data mov ds,ax mov dx,0 ;ds:dx指向字符串的首地址 data:0 mov ah,9 int 21h mov ax,4c00h int 21h code endsend start
二、端口
各種芯片(網(wǎng)卡,顯卡等)都有一組可以由CPU讀寫的寄存器。CPU可以通過這些寄存器讀取數(shù)據(jù),或者操控芯片。CPU把這些寄存器當(dāng)做端口,對(duì)這些寄存器進(jìn)行統(tǒng)一編址。每個(gè)端口宅地址空間中都有一個(gè)地址。
1. in和out指令
訪問端口用in和out
如果:
in al,60h ; 從60h端口讀取數(shù)據(jù)放到al中
注意:只能用ax或者al來存放從端口中讀入的數(shù)據(jù)或要發(fā)送到端口的數(shù)據(jù)。
對(duì)0~255以內(nèi)的端口進(jìn)行讀寫時(shí):
in al,20h
out 20h,al
對(duì)256~65535的端口進(jìn)行讀寫時(shí),端口號(hào)放在dx中:
mov dx,3f8h
in al.dx
ou dx,al
2. shl和shr指令
shl:左移指令,最低位補(bǔ)0,將移出的追后以為寫入CF中
如果是移1位就:
shl al,1
如果移動(dòng)大于1位,必須將移動(dòng)的位數(shù)放在cl中
mov cl,3
shl al,cl
shr是右移,其他與shl一樣
3. CMOS RAM芯片
PC中有一個(gè)靠電池供電CMOS RAM芯片,它包含一個(gè)實(shí)時(shí)種和一個(gè)有128個(gè)存儲(chǔ)單元的RAM存儲(chǔ)器。
它有兩個(gè)端口:
70h:保存要讀取內(nèi)存單元的地址
71h:讀取內(nèi)存單元
CMOS RAM中存儲(chǔ)的時(shí)間信息
0:秒;2:分;
4:時(shí);7:日;
8:月;9:年;
例子:在屏幕顯示月份。
assume cs:codecode segmentstart:mov al,8out 70h,alin al,71hmov ah,almov cl,4shr ah,cland al,00001111badd ah,30h ;0 的ASCII值add al,30hmov bx,0b800hmov es,bxmov byte ptr es:[160*12+40*2],ahmov byte ptr es:[160*12+40*2+2],almov ax,4c00hint 21hcode endsend start
評(píng)論