學(xué)習(xí)匯編--寫(xiě)一個(gè)完整的匯編(一)

匯編指令

  • 匯編有兩類(lèi)指令組成

    • 匯編指令
      如move,add,sub等,有對(duì)應(yīng)的機(jī)器指令,可以被編譯為機(jī)器指令最終被CPU執(zhí)行
    • 偽指令
      如assume,segment,ends,end等。沒(méi)有對(duì)應(yīng)的機(jī)器指令,由編譯器解析,最終不被CPU執(zhí)行
  • 注釋以分號(hào)(;)開(kāi)頭

偽指令

  • segment和ends的作用是定義一個(gè)段,segment代表一個(gè)段的開(kāi)始,ends代表一個(gè)段的結(jié)束
  • 一個(gè)有意義的匯編程序中,至少要有一個(gè)段作為代碼段存放代碼
  • assume:將用作代碼段的code段和CPU中的cs寄存器關(guān)聯(lián)起來(lái)
  • end:編譯器遇到end時(shí),就結(jié)束對(duì)源程序的編譯
  • 退出程序:
    • mov ah,4ch
    • int 21h

中斷

由軟件或者硬件發(fā)出信號(hào),使CPU暫停當(dāng)前的任務(wù),轉(zhuǎn)而去執(zhí)行另一個(gè)段子程序

中斷的分類(lèi)

  • 硬中斷(外中斷),由外部設(shè)備(比如網(wǎng)卡、硬盤(pán))隨機(jī)引發(fā)的,比如當(dāng)網(wǎng)卡收到數(shù)據(jù)包的時(shí)候,就會(huì)發(fā)出一個(gè)中斷

  • 軟中斷(內(nèi)中斷),由執(zhí)行中斷指令產(chǎn)生的,可以通過(guò)程序控制觸發(fā)

      從本質(zhì)上來(lái)講,中斷是一種電信號(hào),當(dāng)設(shè)備有某種事件發(fā)生時(shí),它就會(huì)產(chǎn)生中斷,通過(guò)總線(xiàn)把電信號(hào)發(fā)送給中斷控制器。如果中斷的線(xiàn)是激活的,中斷控制器就把電信號(hào)發(fā)送給處理器的某個(gè)特定引腳。處理器于是立即停止自己正在做的事,跳到中斷處理程序的入口點(diǎn),進(jìn)行中斷處理
    
  • 可以通過(guò)指令int n產(chǎn)生中斷

    • n是中斷碼,內(nèi)存中有一張中斷向量表,用來(lái)存放中斷碼對(duì)應(yīng)中斷處理程序的入口地址
    • CPU在收到中斷信號(hào)后,暫停當(dāng)前執(zhí)行的程序,跳轉(zhuǎn)到中斷碼對(duì)應(yīng)的中斷向量表地質(zhì)處,去執(zhí)行中斷處理程序
      *常見(jiàn)中斷
    • int 10h用于執(zhí)行BIOS中斷
    • int 3是“斷點(diǎn)中斷”,用于調(diào)試程序
    • int 21h用于執(zhí)行DOS系統(tǒng)功能調(diào)用,AH寄存器存儲(chǔ)功能號(hào)

DOS系統(tǒng)功能調(diào)用

  • DOS系統(tǒng)功能調(diào)用
    • 由DOS提供的一組實(shí)現(xiàn)特殊功能的子程序供程序員在編寫(xiě)自己的程序時(shí)調(diào)用,以減輕編程的工作量
    • 涉及屏幕顯示、文件管理、I/O管理等等
    • 每個(gè)子程序都有一個(gè)功能號(hào),所有的功能調(diào)用的格式都是一致的。調(diào)用的步驟大致如下:
      • 系統(tǒng)功能號(hào)送到寄存器AH中;
      • 入口參數(shù)送到指定的寄存器中;
      • 用INT 21H指令執(zhí)行功能調(diào)用;
      • 根據(jù)出口參數(shù)分析功能調(diào)用執(zhí)行情況。
這是一段完整的匯編代碼
將數(shù)據(jù)存放在ds中,并將ds中的數(shù)據(jù)以字節(jié)的形式倒敘存入棧中

assume cs:code
code segment

mov ax,2000h
mov ds,ax
mov [0],1122h
mov [2],3344h
mov [4],5566h
mov [6],7788h
mov [8],99aah

mov ax,3000h
mov ss,ax
mov sp,ah
push [8]
push [6]
push [4]
push [2]
push [0]

mov ah,4ch
int 21h

code ends
end

loop指令

  • loop指令和cx寄存器配合使用,用于循環(huán)操作,類(lèi)似高級(jí)語(yǔ)言的do:while
  • 使用格式
    mov cx,循環(huán)次數(shù)
標(biāo)號(hào):
    循環(huán)執(zhí)行的程序代碼
    loop 標(biāo)號(hào)
  • 每執(zhí)行一次loop 標(biāo)號(hào) cx中的值減一,如果cx-1不等于0,跳轉(zhuǎn)到標(biāo)號(hào)位置繼續(xù)執(zhí)行,否則執(zhí)行l(wèi)oop指令后面的指令
  • loop $ 一直執(zhí)行這一句loop,直到cx=0,用來(lái)延時(shí)

示例1可以改寫(xiě)為

    assume cs:code
    code segment

    mov ax,2000h
    mov ds,ax
    mov bx,1122h
    mov cx,5;循環(huán)次數(shù)
    mov si,0h;si:源變址寄存器可用來(lái)存放相對(duì)于DS段之源變址指針
s:  mov [si],bx;因?yàn)閇]中不能存放數(shù)據(jù)寄存器、段寄存器和控制寄存器
    add bx,2222h
    add si,2
    loop s;每次執(zhí)行先讓cx-1,然后判斷cx是否為0
    
    mov ax,3000h
    mov ss,ax
    mov sp,0ah;這里需要sp指向10處,不能直接寫(xiě)ah
    mov si,8h
p:    push [si]
    sub si,2
    loop p
    
    mov ah,4ch
    int 21h

    code ends
    end

代碼分段

assume cs:code,ds:data,ss:stack

data segment
    db 20 dup(0)
data ends

stack segment
    db 20 dup(0)
    age dw 20h;age標(biāo)號(hào) 編譯器會(huì)將其轉(zhuǎn)成地址值
stack ends

code segment
    
    ;配置ds,ss如果不配置,data,stack里面也沒(méi)數(shù)據(jù)的話(huà)三個(gè)段地址隨機(jī)并相同
    ;data,stack里面有數(shù)據(jù)的話(huà)會(huì)隨機(jī)分配地址,三個(gè)段地址不相同
    ;如果配置
    
    mov ax,2000h
    mov ds,ax
    
    mov ax,3000h
    mov ss,ax
 ;   mov sp,14h;不用指定sp,因?yàn)樯厦鎠tack已經(jīng)指定棧段和大小了
   
    mov [0],1122h
    mov age,1122h;age物理內(nèi)存地址

    push 1122h
    
    mov ah,4ch
    int 21h
    
code ends

end

練習(xí)

  ;0x00010h 11h
  ;0x00011h 22h
  ;0x00012h 33h
  ;求三個(gè)字節(jié)的和
    
 ;   mov ax,0001h
 ;   mov ds,ax
    
 ;   mov [0],11h
 ;   mov [1],22h 
 ;   mov [2],33h
     
 ;   mov al,[0]
 ;   add al,[1]
 ;   add al,[2]

如果上面代碼中數(shù)據(jù)段保存的值是0xff,0xff,0xff,使用上面的計(jì)算方法,會(huì)造成溢出

assume cs:code
code segment 
start: 
  ;0x00010h ffh
  ;0x00011h ffh
  ;0x00012h ffh
  ;求三個(gè)字節(jié)的和
  ;這種情況下在使用代碼1的方式,在相加的過(guò)程中,al溢出
    mov ax,0001h
    mov ds,ax
   
    mov [0],0xff;寫(xiě)ffh會(huì)報(bào)錯(cuò),無(wú)法識(shí)別這個(gè)十六進(jìn)制 
    mov [1],0xff
    mov [2],0xff
    
    mov bx,0h
    
    mov al,[0]
    mov ah,0h
    add bx,ax
    
    mov al,[1]
    mov ah,0h
    add bx,ax
    
    mov al,[2]
    mov ah,0h
    add bx,ax
    
    mov ah,4ch
    int 21h
    
code ends
end  start
使用loop指令
assume cs:code
code segment 
start: 
  ;0x00010h ffh
  ;0x00011h ffh
  ;0x00012h ffh
  ;求三個(gè)字節(jié)的和
  ;這種情況下在使用代碼1的方式,在相加的過(guò)程中,al溢出
    mov ax,0001h
    mov ds,ax
   
    mov [0],0xff;寫(xiě)ffh會(huì)報(bào)錯(cuò),無(wú)法識(shí)別這個(gè)十六進(jìn)制 
    mov [1],0xff
    mov [2],0xff
    
    mov bx,0h
    mov dx,0h
    mov cx,3h 
s:  mov al,[bx];如果這里換成dx報(bào)語(yǔ)法錯(cuò)誤
    mov ah,0h
    add dx,ax
    add bx,1
    loop s

    mov ah,4ch
    int 21h
    
code ends
end  start
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容