David.Ko

          Follow my heart!
          posts - 100, comments - 11, trackbacks - 0, articles - 0
             :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

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

          Posted on 2007-09-30 08:21 David.Ko 閱讀(228) 評論(0)  編輯  收藏 所屬分類: 病毒
          基本原理
          2.1 8086/8088
          IBM PC中央處理單元(Central Processing Unit)是微處理器Inter 8088,8088是8086是小的版本.對于編寫程序而言,兩者幾乎完全相同.兩者之間的差別是在于:它們對外的溝通.8086和外界溝通時是經(jīng)由16位的輸入輸出通道,內(nèi)存存取也是每次以16位為單位,8088和8086極為相似,但是它和外界溝通時就必須經(jīng)由16位的通道.
          2.1.1 寄存器
          8086/8088的結(jié)構(gòu)簡單,其中包含了一組一般用途的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的用途也沒有特別的限制,但是卻不能分成兩個字節(jié).另外寄存器SP主要是用來當(dāng)做堆棧指針.除此之外,還有四個非常重要的段寄存器(Segment Register):CS,DS,SS,ES.指令指針(Instru -ction pointer)IP是用來控制目前CPU執(zhí)行到哪一個指令.
          8086設(shè)計時考慮到要和8位的CPU8080兼容.8位的計算機是使用兩個字節(jié)(亦即16位)來定址,因此其定址空間可以達64K字節(jié).16位的CPU在地址設(shè)定上選擇了完全不同的方法.CPU以段(Segment)為單位,每一段范圍內(nèi)包括64K字節(jié),而內(nèi)存中則可以包含許多段.所以,操作系統(tǒng)可以在一個段內(nèi)執(zhí)行.而使用者的程序則可以在另一個段內(nèi)執(zhí)行.在一個段內(nèi),程序包可以把計算機視為只有64K字節(jié)內(nèi)存空間.因此原先8位計算機上執(zhí)行的程序就可以很容易地移植到16位計算機上.除此之外,內(nèi)存段也可以彼此重疊,因而兩個不同的程序就可以共用某一塊內(nèi)存.段值是以寄存器來設(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)是一臺計算機上許多復(fù)雜操作的關(guān)鍵所在.8086提供了以下幾種尋址方法:立即尋址,內(nèi)存間接尋址, 寄存器間接尋址等.
          立即尋址,直接使用數(shù)字.
          內(nèi)存間接尋址,數(shù)值存放在數(shù)據(jù)段中的某個位置.
          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ù).寄存器間接存取時,最多只能使用瑪個基址寄存器各 一個索引寄存器.
          以上的尋址方式可以做不同的結(jié)合,因此組合后的結(jié)果很多.
          2.1.3 標志
          8086有9個一位的標志(Flag),它們可以用指示CPU的各種狀態(tài).以下是9個標志的簡介:
          CF(Carry Flag):CF為1時就表示算術(shù)運算的結(jié)果超出正確的長度.
          PF(Parity Flag):PF為1就表示使用偶校驗,PF為0就表示使用奇校驗.
          AF(Auxiliary Carry Flag):和CF相同,只是它使用在低4位的結(jié)果.AF通常都使用在20位的地址計算上.
          ZF(Zero Flag):ZF為1就表示運算結(jié)果是0,否則ZF就為0.
          SF(Sign Flag):SF為1就表示運算結(jié)果的最高位是1,否則SF就為0.
          TF(Trap Flag):TF為1,CPU就單步地執(zhí)行,在這種模式下每完成一個指令就發(fā)生一個特殊的中斷.
          IF(Interrupt Enable Flag):IF為1,允許CPU接收外界的中斷,否則IF就為0.
          DF(Direction Flag):這個標志使用在循環(huán)指令,譬如:MOVS,MOVSB,MOVSW,CMPS,CMPSB和CMPSW.如果DF為1,循環(huán)運行時就使地 址值往前增加.如果DF為0,則使地址往后減少.
          OF(Over Flag):OF為1,表示一個考慮正負號的運算超出了正確的字節(jié)的長度.
          2.1.4 循環(huán)
          所有的循環(huán)指令都是以CX作為計數(shù)器.一個循環(huán)會反復(fù)地執(zhí)行直到CX等于某一特定值為止.以下的程序就是利用反復(fù)地相加,完成 兩個數(shù)的相乘.
          mov ax,0
          mov cx,4
          next: add ax,6
          loop next
          在上面的程序中,LOOP指令執(zhí)行時會把CX減1,并且檢查CX的內(nèi)容;如果CX等于0,就轉(zhuǎn)移到下一條指令,否則就跳到NEXT標示的地方 執(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ù)的基本單位.計算機的存儲結(jié)構(gòu)是8位的字節(jié),但是CPU本身處理數(shù)據(jù)則是以16位為單位.在內(nèi)存中,都遵 循一個原則,即:高高低低的存儲方式.高字節(jié)對應(yīng)高地址,低字節(jié)對應(yīng)低地址.
          下面是一個簡單程序,在AX中放入一個字節(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
          主站蜘蛛池模板: 建始县| 太仓市| 辽阳县| 乃东县| 丰顺县| 宣武区| 柘城县| 阿拉善盟| 永吉县| 安义县| 邵阳市| 谢通门县| 巴林左旗| 清远市| 淳化县| 黎平县| 三原县| 青河县| 贵德县| 达州市| 宁陵县| 闽侯县| 阿巴嘎旗| 青河县| 潜江市| 利辛县| 神木县| 海安县| 宝鸡市| 浦东新区| 尚志市| 石阡县| 沧源| 沙洋县| 嘉义市| 克山县| 绍兴县| 株洲县| 通许县| 剑川县| 岑巩县|