匯編語言

《匯編語言》第四版,王爽

  • 匯編語言由以下組成:
    • 匯編指令:有對應的機器碼助記符
    • 僞指令:無對應機器碼,由編譯器執行
    • 其他符號:編譯器識別
  • 在内存或磁盤中指令和數據沒有任何區別。計算機=信息+位
  • CPU在内存中讀取數據
  • 三類信息:
    • 地址信息
    • 控制信息
    • 數據信息
  • 示例:
    • address = [0,1,2,3,4,5,6,7,8], data = [10,11,2,13,34,12,34,56,12]
    • address is 3
    • data is 13
    • read address
    • write 26 to address
    • data = [10,11,2,26,34,12,34,56,12]
    • CPU讀寫過程
  • 匯編指令為 MOV ax,[3]
  • 地址總綫
    • CPU有N個地址綫,則這個CPU最多可以尋找2的N次方個内存單元
  • 數據總綫
    • 數據總綫數為每次傳輸的數據可以是多少位,如8個數據綫的讀取16位要傳送兩次
  • 控製總線
    • 對外部器件的控制,最基本的是讀寫
  • 各類存儲器芯片
    • 讀寫分爲兩類:RAM(随机存储器)關機會丟失數據 ROM(只读存储器)關機不會丟失
    • BIOS是ROM有嘗試提供的,每個器件的BIOS都是獨一無二的顯卡的和網卡的不同
    • 顯卡有RAM即顯存
  • CPU = [RAM主存儲器],[ROM系統BIOS],[RAM主存儲器:内存條],[顯卡:RAM: ROM顯卡BIOS]->顯示器,[ROM:網卡BIOS]
  • 内存地址空間
    • 每個邏輯存儲器都占一段地址空間,寫入不同地址,作用不同,用的時候查
  • 寄存器
    • 寄存器是可以用指令讀寫的部件:8086有14個寄存器:AX,BX,CX,DX,SI,DI,SP,BP,IP,CS,SS
    • AX,BX,CX,DX存放一般性數據,被稱爲通用寄存器。這四個寄存器可以分爲兩個8位寄存器****__H和_L
    • 字為16位,32位,64位又可以分爲高低字節
    • 超8計算,產生的進位并不會保存在高8位寄存器中,傳輸和運算時,兩個操作數的位數應當一致
    • 8086CPU采用兩個16位地址合成一個20位的物理地址
    • {[段地址] [偏移地址] } ->地址加法器 = 20位物理地址
    • 地址加法器實現方法:段地址 x 16 + 偏移地址
    • x 16 也可以説成左移四位(Bin)
  • 段的概念
    • 内存并沒有分段,我們是用分段的方式管理地址
    • 段地址必然是16的倍數,偏移地址16位,尋址能力64 KB
    • 段寄存器有四個:CS, DS, SS ES
    • CS和IP
      • CS為代碼段寄存器,IP為指令指針寄存器 CPU將CS x 16 + IP開始讀取指令執行,任意時刻CS:IP都作爲指令執行 IP 在執行後會自動增加指令長度便於執行下一個指令
      • RESET后cs 被設置為 FFFHF; IP 被設置爲 0000H
      • 修改CS:IP的方法:jmp 段地址:偏移地址 只修改ip則為 jmp 某一合法寄存器
    • 代碼段
      • 可以把一個小於等於64 KB的一組内存單元 存放代碼 但是CPU不會自動執行需要我們設置測cs:ip
    • 實驗一
      • Debug
        • R查看和改變寄存器内容
        • D查看内存中的内容
        • E改寫内存中的内容
        • U把機器指令翻譯爲匯編指令
        • T執行一條機器指令
        • A以匯編指令格式在内存中寫入一個機器指令
  • 寄存器 内存訪問
    • DS 和 [address]

      • DS存放要訪問的數據段地址
      • [···]表示一個内存單元,[···]表示的是偏移地址,自動以ds作爲段地址,不能直接把立即數傳遞給DS
    • 字的傳送

    • mov 可以在寄存器和内存之間進行字節型數據傳送 mov ax,1000H mov ds ax mov [0] ax地址為1000H

    • mov add sub指令

      • mov
        • mov 寄存器,數據
        • mov 寄存器,寄存器
        • mov 寄存器,内存單元
        • mov 内存單元,寄存器
        • mov 段寄存器,寄存器
    • 數據段

      • 可以將一段小於等於64 kb的内存定義為一個數據段
      • 頂部存取的黑盒子
      • push 入棧 pop 出棧 都是以字為單位
      • SS 段寄存器 sp寄存器 ss:sp始終指向棧頂元素
      • 棧底是從高地址到低地址
      • 空棧為最高地址的后一個字節
      • 超界后其他内存數據會被覆蓋
      • 使用棧要先設置ss寄存器
    • 數據段 代碼段 棧段 都和CS:IP 有關 代碼段 也可以是數據段 和棧段 這些都和DS CS SS有關


    • 第一個程序

      • assume cs:codesg ;代碼段 assume假設 説明關聯 cs
        codesg segment ;僞指令 格式 段名 segment
        		mov ax,0123H
        		mov bx,0456H
        		add ax,bx
        		add ax,ax
        		
        		mov ax 4c00H ;實現程序返回
        		int 21H
        codesg ends ;代碼段結束 僞指令 格式 段名 ends
        
        end ;結束編譯
        assume cs:codesg
        codesg segment
        
        	mov ax,2000H
        	mov ss,ax
        	mov sp,0
        	add sp,10
        	pop ax
        	pop bx
        	push ax
        	push bx
        	pop ax
        	pop bx
        	
        	mov ax,4c00H
        	int 21H
        
        codesg ends
        
        end
        
      • 編程-> 編譯 -> 鏈接 -> 加載 -> 内存->CPU

      • [内存, SA:0000, PSP(256 bytes), SA + 10H程序 , CS:IP = SA+10H:0]

    • [寄存器]同樣表示内存單元

    • inc bx 即bx内容+1

    • loop指令

      • loop 標號 cx存放循環次數 每次執行后--cx

      • 計算2^12

      • assume cs:code
        code segment
        	mov ax,2
        	mov cx,11
        s: add ax,ax
        	loop s
        	
        	mov ax,4cooH
        	
        code ends
        
        end
        
      • 匯編語言 標號代表地址 表示標記了一個地址

      • 匯編語言中數據不能以字母開頭

      • mov ax,ds:[0] 表示内存單元

      • mov ax,[bx]

      • mov ax,[0] 源程序中等價於 mov ax,0

      • ds:[0]段前綴 es: cs: ss:

      • 尋找安全的空間編程 0:200 - 0:2ff 安全

    • 數據空間

      • dw 定義字型數據

      • end還可以通知程序入口 dw 0

      • 多個段的程序

      • assume cs:code, ds:data, ss:stack
        data segment
        	dw 0123h, 0456h,0789h,0abch,0defh
        data ends
        
        stack segment
        	dw 0,0,0,0,0,0,0
        stack ends
        
        code segment 
        start : mov ax, stack
        		mov ss,ax
        		mov sp,20h
        		mov ax,data
        		mov ds,ax
        		
        		mov bx,0
        		mov cx,8
        s:      push [bx]
        		add bx,2
        		loop s
        		mov bx,0
        		mov cx,8
        s0:		pop[bx]
        		add bx,2
        		loop s0
        		
        		mov ax,4c00h
        		int 21h
        code ends
        end start
        
    • and 和 or指令

      • and 按位與 or 按位或
    • ASCII

      • 61H表示'a'
    • SI 和 DI 功能與bx相似

    • 雙重循環需要用dx保存cx的值

    • reg 寄存器 sreg 段寄存器

      • 只有bx,si,di,bp可以用作内存單元尋址
      • 數據處理分爲三類:讀取,寫入,運算
      • idata常數->立即數 ,指令中直接給出
      • 寄存器存儲的值
      • 尋址方式總結:p164
    • 字操作和字節操作

      • 可以用word ptr 修飾字操作 mov word ptr ds:[0],1
      • inc word ptr [bx]
      • byte ptr 字節操作
    • div

      • 除數8位和16位 放在reg或内存單元中
      • p169
      • db dw
    • 僞指令 dd

      • 雙字
    • dup 數據的重複

      • db 3 dup(0)
    • 操作符 offset

      • 取得標號的偏移地址
      • nop占用一個字節
      • mov ax,offset start
    • jmp指令

      • 修改ip 或 cs:ip
      • 需要的信息
        • 轉移的目的地址
        • 轉移的距離 段閒轉移 段内短轉移 段内近轉移
      • jmp short 短轉移
        • 傳入的信息沒有目的地址
        • 接受的機器指令為jmp ip會修改
        • 修改ip的是想方法是得到移動的位移 EB 03 ip+3 包含的信息是位移
        • short 支持8位的位移-128-127
        • jmp near ptr 標號 16位位移
      • jmp far ptr 標號 遠轉移 包含了目的地址
      • 在内存中的jmp
        • p183
      • jcxz指令
        • 條件轉移 短轉移
        • 格式:jcxz 標號 (if cx == 0) 就到表好處執行
      • loop短轉移
      • 轉移會有檢測 超界會不通過
    • CALL RET指令

      • 可以用於設計子程序 都是轉移指令 可以修改 ip 或者 cs:ip
      • call 標號 入棧 cs:ip ret出棧
      • call 標號
        • push IP
        • jmp near ptr 標號
      • call far ptr 標號
        • push CS
        • push IP
        • jmp far ptr 標號
      • ret
        • pop
      • retf
        • pop ip
        • pop cs
      • mul
        • 乘法
      • 編寫子程序待完成
    • 標志寄存器 (第十一章)

      • flag寄存器
        • 16位寄存器按位起作用
        • [ , , , , , OF, DF,IF,TF,SF,ZF, ,AF, PF, ,CF]
        • 02467891011這幾個位置都有特殊含義
        • ZF 零標志位 記錄結果是否爲0
          • mov ax,1
          • sub ax,1
          • 此時zf=1
        • PF奇偶標志位
          • 奇數個1,pf = 0
          • 偶數個1,pf = 1
        • SF符號標志位
          • 結果為負,sf=1
        • CF標志位
          • 進位標志,無符號運算時記錄最高位想假想位的進位
          • 8位[1,1,1,1,1,1,1,1] + 1
          • cf = 1 [0,0,0,0,0,0,0,0]
          • 進位保存在cf
        • OF 標志 有符號運算
          • 溢出標志位 溢出of =1
          • cf 無符號運算
        • adc 帶進位的加法
          • adc opNum1,opNum2
          • opNum1 = o1 + o2 + CF
        • sbb 帶借位的減法
          • o1=o1- o2 - cf
        • cmp 比較指令
          • cmp 1,2
          • 1-2 不保存結果 設置標志寄存器
        • je 關聯zf的轉移
          • if (zf == 1) jmp
          • jne (zf != 1)
        • jb cf==1
        • jnb cf != 1
        • ja cf == 0 && zf == 0
        • jna cf ==1 || zf == 1
        • DF 標志 df = 0 (si,di inc)反之--
        • movsb 串傳送指令 +1 or -1
        • movsw +2 or -2 都是對si,di
        • rep根據cx 重複執行movsb指令
        • cld 設置df=0
        • std 設置df=1
        • pushf popf 對標志寄存器進行棧操作
      • 内中斷 cpu外部或内部產生的特殊信息 接到指令后不再向下執行而是處理特殊信息
        • 内中斷來源
          • 除法錯誤 0
          • 單步執行 1
          • into 4
          • int 格式 int n 提供cpu 類型中斷碼
          • 終端向量表 1024 0000 - 3ff
          • 終端過程
            • 獲取中斷類型碼
            • 標志寄存器入棧
            • TF IF設置為0
            • cs入棧
            • IP入棧
            • 從内存地址為類型終端碼4 和4 + 2的兩個字單元讀取設置 IP和CS
            • 中斷處理完后恢復CS IP
            • 過程
            • 取得N
            • pushf
            • TF = 0 IF = 0
            • push CS
            • push IP
            • IP = (N*4),CS = (N*4+2)
            • 中斷處理程序編寫
              • 保存寄存器
              • 處理終端
              • 回復寄存器
              • iret 返回
                • iret
                • pop IP
                • pop CS
                • popf
          • TF為1時產生單步中斷
          • int n號中斷
            • BIOS中斷 10h中斷
            • int 21h DOS中斷
      • 端口讀寫 只有in out
        • 主板接的外部芯片顯卡,網卡之類的
        • shl 和 shr
          • 邏輯左移,邏輯右移 最後移出的一位寫入cf中
    • 外中斷

      • 可屏蔽的中斷 IF=1可以 IF=0不餉應
        • sti設置if = 1
        • cli 設置if = 0
      • 不可屏蔽中斷
        • 中斷固定為2
        • int 9處理鍵盤輸入輸出
        • in al,60h讀出鍵盤輸入
    • 16章和17章

      • 磁盤讀寫