用匯編編寫(xiě)DOS下的內(nèi)存駐留程序(2)

字號(hào):

基本原理
    2.1 8086/8088
       IBM PC中央處理單元(Central Processing Unit)是微處理器Inter 8088,8088是8086是小的版本.對(duì)于編寫(xiě)程序而言,兩者幾乎完全相同.兩者之間的差別是在于:它們對(duì)外的溝通.8086和外界溝通時(shí)是經(jīng)由16位的輸入輸出通道,內(nèi)存存取也是每次以16位為單位,8088和8086極為相似,但是它和外界溝通時(shí)就必須經(jīng)由16位的通道.
       2.1.1 寄存器
        8086/8088的結(jié)構(gòu)簡(jiǎn)單,其中包含了一組一般用途的16位寄存器.AX,BX,CX,DX,BP,SI,DI.其中AX,BX,CX,DX還可以分成8位的寄存 器,譬如:AX可分為AH,AL;BX可分為BH,BL;CX可分為CH,CL;DX可分為DH,DL.寄存器BP,SI,DI的用途也沒(méi)有特別的限制,但是卻不能分成兩個(gè)字節(jié).另外寄存器SP主要是用來(lái)當(dāng)做堆棧指針.除此之外,還有四個(gè)非常重要的段寄存器(Segment Register):CS,DS,SS,ES.指令指針(Instru -ction pointer)IP是用來(lái)控制目前CPU執(zhí)行到哪一個(gè)指令.
        8086設(shè)計(jì)時(shí)考慮到要和8位的CPU8080兼容.8位的計(jì)算機(jī)是使用兩個(gè)字節(jié)(亦即16位)來(lái)定址,因此其定址空間可以達(dá)64K字節(jié).16位的CPU在地址設(shè)定上選擇了完全不同的方法.CPU以段(Segment)為單位,每一段范圍內(nèi)包括64K字節(jié),而內(nèi)存中則可以包含許多段.所以,操作系統(tǒng)可以在一個(gè)段內(nèi)執(zhí)行.而使用者的程序則可以在另一個(gè)段內(nèi)執(zhí)行.在一個(gè)段內(nèi),程序包可以把計(jì)算機(jī)視為只有64K字節(jié)內(nèi)存空間.因此原先8位計(jì)算機(jī)上執(zhí)行的程序就可以很容易地移植到16位計(jì)算機(jī)上.除此之外,內(nèi)存段也可以彼此重疊,因而兩個(gè)不同的程序就可以共用某一塊內(nèi)存.段值是以寄存器來(lái)設(shè)定的,而實(shí)際的地址值則是把段值(16位)往左移4位,然后再加上16位的位移(Offset),因此構(gòu)成20位的地址值.所以8086可以直接做20位的地址,也就是可能存取到一兆字節(jié)的內(nèi)存.在這一兆字節(jié)的內(nèi)存中,IBM PC保留了最前面的320K字節(jié)給系統(tǒng)的ROM BIOS和顯示內(nèi)存,因此使用者最多也就能使用640K字節(jié).
       2.1.2 尋址方式
        尋址方式(Addressing mode)是一臺(tái)計(jì)算機(jī)上許多復(fù)雜操作的關(guān)鍵所在.8086提供了以下幾種尋址方法:立即尋址,內(nèi)存間接尋址, 寄存器間接尋址等.
        立即尋址,直接使用數(shù)字.
        內(nèi)存間接尋址,數(shù)值存放在數(shù)據(jù)段中的某個(gè)位置.
        mov bx,foo
        foo dw 5
        寄存器間接尋址.有兩種寄存器可以使用在這種尋址方式下:基址寄存器(Base Register)和索引寄存器(Index Register).基址寄存 器分別是BX和BP,索引寄存器則是SI和DI.在這種尋址方式下,寄存器存放了數(shù)據(jù)段中的地址值.
        mov ax,0F000h
        mov es,ax
        mov si,0FFFEh
        mov dl,byte ptr es:[si]
       上面的程序使用間接尋址方式,由寄存器SI讀出位于F000:FFFE位置的數(shù)據(jù).寄存器間接存取時(shí),最多只能使用瑪個(gè)基址寄存器各 一個(gè)索引寄存器.
       以上的尋址方式可以做不同的結(jié)合,因此組合后的結(jié)果很多.
       2.1.3 標(biāo)志
        8086有9個(gè)一位的標(biāo)志(Flag),它們可以用指示CPU的各種狀態(tài).以下是9個(gè)標(biāo)志的簡(jiǎn)介:
         CF(Carry Flag):CF為1時(shí)就表示算術(shù)運(yùn)算的結(jié)果超出正確的長(zhǎng)度.
       PF(Parity Flag):PF為1就表示使用偶校驗(yàn),PF為0就表示使用奇校驗(yàn).
       AF(Auxiliary Carry Flag):和CF相同,只是它使用在低4位的結(jié)果.AF通常都使用在20位的地址計(jì)算上.
       ZF(Zero Flag):ZF為1就表示運(yùn)算結(jié)果是0,否則ZF就為0.
       SF(Sign Flag):SF為1就表示運(yùn)算結(jié)果的位是1,否則SF就為0.
       TF(Trap Flag):TF為1,CPU就單步地執(zhí)行,在這種模式下每完成一個(gè)指令就發(fā)生一個(gè)特殊的中斷.
       IF(Interrupt Enable Flag):IF為1,允許CPU接收外界的中斷,否則IF就為0.
        DF(Direction Flag):這個(gè)標(biāo)志使用在循環(huán)指令,譬如:MOVS,MOVSB,MOVSW,CMPS,CMPSB和CMPSW.如果DF為1,循環(huán)運(yùn)行時(shí)就使地 址值往前增加.如果DF為0,則使地址往后減少.
        OF(Over Flag):OF為1,表示一個(gè)考慮正負(fù)號(hào)的運(yùn)算超出了正確的字節(jié)的長(zhǎng)度.
       2.1.4 循環(huán)
        所有的循環(huán)指令都是以CX作為計(jì)數(shù)器.一個(gè)循環(huán)會(huì)反復(fù)地執(zhí)行直到CX等于某一特定值為止.以下的程序就是利用反復(fù)地相加,完成 兩個(gè)數(shù)的相乘.
        mov ax,0
        mov cx,4
       next: add ax,6
        loop next
       在上面的程序中,LOOP指令執(zhí)行時(shí)會(huì)把CX減1,并且檢查CX的內(nèi)容;如果CX等于0,就轉(zhuǎn)移到下一條指令,否則就跳到NEXT標(biāo)示的地方 執(zhí)行.
       也可以用下面的程序完成相同的功能:
       mov ax,0
        mov cx,4
       next:
        add ax,6
        dec cx
        cmp cx,0
        jne next
       2.1.5 內(nèi)存的數(shù)據(jù)結(jié)構(gòu)
        8088是以字節(jié)為存取數(shù)據(jù)的基本單位.計(jì)算機(jī)的存儲(chǔ)結(jié)構(gòu)是8位的字節(jié),但是CPU本身處理數(shù)據(jù)則是以16位為單位.在內(nèi)存中,都遵 循一個(gè)原則,即:高高低低的存儲(chǔ)方式.高字節(jié)對(duì)應(yīng)高地址,低字節(jié)對(duì)應(yīng)低地址.
       下面是一個(gè)簡(jiǎn)單程序,在AX中放入一個(gè)字節(jié)的內(nèi)容并顯示:
        cseg segment
        org 100h
        assume cs:cseg,ds:cseg
        start:
        mov bx,cs
        mov ds,bx
        mov ah,'H'
        mov al,'L'
        mov test,ax
        mov al,[si] ;First byte of test
        call dchar
        mov al,[si+1] ;Second byte of test
        call dchar
        ret
        ;Display the character contained in AL
        dchar proc
        push ax
        push bx
        mov bh,1
        mov ah,0eh
        int 10h
       pop bx
       pop ax
       ret
       dchar endp
       test dw ?
       cseg ends
        end start