David.Ko

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

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

          Posted on 2007-09-30 08:21 David.Ko 閱讀(224) 評論(0)  編輯  收藏 所屬分類: 病毒
          基本原理
          2.1 8086/8088
          IBM PC中央處理單元(Central Processing Unit)是微處理器Inter 8088,8088是8086是小的版本.對于編寫程序而言,兩者幾乎完全相同.兩者之間的差別是在于:它們對外的溝通.8086和外界溝通時是經由16位的輸入輸出通道,內存存取也是每次以16位為單位,8088和8086極為相似,但是它和外界溝通時就必須經由16位的通道.
          2.1.1 寄存器
          8086/8088的結構簡單,其中包含了一組一般用途的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的用途也沒有特別的限制,但是卻不能分成兩個字節.另外寄存器SP主要是用來當做堆棧指針.除此之外,還有四個非常重要的段寄存器(Segment Register):CS,DS,SS,ES.指令指針(Instru -ction pointer)IP是用來控制目前CPU執行到哪一個指令.
          8086設計時考慮到要和8位的CPU8080兼容.8位的計算機是使用兩個字節(亦即16位)來定址,因此其定址空間可以達64K字節.16位的CPU在地址設定上選擇了完全不同的方法.CPU以段(Segment)為單位,每一段范圍內包括64K字節,而內存中則可以包含許多段.所以,操作系統可以在一個段內執行.而使用者的程序則可以在另一個段內執行.在一個段內,程序包可以把計算機視為只有64K字節內存空間.因此原先8位計算機上執行的程序就可以很容易地移植到16位計算機上.除此之外,內存段也可以彼此重疊,因而兩個不同的程序就可以共用某一塊內存.段值是以寄存器來設定的,而實際的地址值則是把段值(16位)往左移4位,然后再加上16位的位移(Offset),因此構成20位的地址值.所以8086可以直接做20位的地址,也就是可能存取到一兆字節的內存.在這一兆字節的內存中,IBM PC保留了最前面的320K字節給系統的ROM BIOS和顯示內存,因此使用者最多也就能使用640K字節.
          2.1.2 尋址方式
          尋址方式(Addressing mode)是一臺計算機上許多復雜操作的關鍵所在.8086提供了以下幾種尋址方法:立即尋址,內存間接尋址, 寄存器間接尋址等.
          立即尋址,直接使用數字.
          內存間接尋址,數值存放在數據段中的某個位置.
          mov bx,foo
          foo dw 5
          寄存器間接尋址.有兩種寄存器可以使用在這種尋址方式下:基址寄存器(Base Register)和索引寄存器(Index Register).基址寄存 器分別是BX和BP,索引寄存器則是SI和DI.在這種尋址方式下,寄存器存放了數據段中的地址值.
          mov ax,0F000h
          mov es,ax
          mov si,0FFFEh
          mov dl,byte ptr es:[si]
          上面的程序使用間接尋址方式,由寄存器SI讀出位于F000:FFFE位置的數據.寄存器間接存取時,最多只能使用瑪個基址寄存器各 一個索引寄存器.
          以上的尋址方式可以做不同的結合,因此組合后的結果很多.
          2.1.3 標志
          8086有9個一位的標志(Flag),它們可以用指示CPU的各種狀態.以下是9個標志的簡介:
          CF(Carry Flag):CF為1時就表示算術運算的結果超出正確的長度.
          PF(Parity Flag):PF為1就表示使用偶校驗,PF為0就表示使用奇校驗.
          AF(Auxiliary Carry Flag):和CF相同,只是它使用在低4位的結果.AF通常都使用在20位的地址計算上.
          ZF(Zero Flag):ZF為1就表示運算結果是0,否則ZF就為0.
          SF(Sign Flag):SF為1就表示運算結果的最高位是1,否則SF就為0.
          TF(Trap Flag):TF為1,CPU就單步地執行,在這種模式下每完成一個指令就發生一個特殊的中斷.
          IF(Interrupt Enable Flag):IF為1,允許CPU接收外界的中斷,否則IF就為0.
          DF(Direction Flag):這個標志使用在循環指令,譬如:MOVS,MOVSB,MOVSW,CMPS,CMPSB和CMPSW.如果DF為1,循環運行時就使地 址值往前增加.如果DF為0,則使地址往后減少.
          OF(Over Flag):OF為1,表示一個考慮正負號的運算超出了正確的字節的長度.
          2.1.4 循環
          所有的循環指令都是以CX作為計數器.一個循環會反復地執行直到CX等于某一特定值為止.以下的程序就是利用反復地相加,完成 兩個數的相乘.
          mov ax,0
          mov cx,4
          next: add ax,6
          loop next
          在上面的程序中,LOOP指令執行時會把CX減1,并且檢查CX的內容;如果CX等于0,就轉移到下一條指令,否則就跳到NEXT標示的地方 執行.
          也可以用下面的程序完成相同的功能:
          mov ax,0
          mov cx,4
          next:
          add ax,6
          dec cx
          cmp cx,0
          jne next
          2.1.5 內存的數據結構
          8088是以字節為存取數據的基本單位.計算機的存儲結構是8位的字節,但是CPU本身處理數據則是以16位為單位.在內存中,都遵 循一個原則,即:高高低低的存儲方式.高字節對應高地址,低字節對應低地址.
          下面是一個簡單程序,在AX中放入一個字節的內容并顯示:
          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
          主站蜘蛛池模板: 军事| 邵阳市| 宁晋县| 和田县| 辽阳县| 东光县| 正蓝旗| 原平市| 甘谷县| 得荣县| 喜德县| 宜丰县| 顺平县| 乐山市| 交口县| 弥渡县| 石家庄市| 古浪县| 辽宁省| 林州市| 出国| 亳州市| 永靖县| 玉林市| 拉萨市| 江安县| 漾濞| 大连市| 辽中县| 桐庐县| 阜阳市| 乌兰察布市| 馆陶县| 兴仁县| 沅陵县| 临桂县| 洪泽县| 罗平县| 濮阳县| 冀州市| 喜德县|