常見匯編代碼


# 常見匯編代碼 #

1. 編寫程序:比較AX,BX,CX中帶符號數的大小,將最大的數放在AX中

        code segment
         assume cs:code
        
         mov ax,32
         mov bx,74
         mov cx,23
        
        sort: cmp ax,bx
              jge X          ;如果ax大於等於bx就跟cx比較
              xchg ax,bx
            X:cmp ax,cx       ;如果ax大於cx
              jge Y
              xchg ax,cx 
            Y:int 21h
              mov ax,4c00h
        code ends
             end sort

2.要求對鍵盤輸入的小寫字母用大寫字母顯示出來

        code segment
         assume cs:code
        
        start: mov ah,1
            int 21h
           
            cmp al,'a'      
            jz error
            cmp al,'z'
            ja error
            sub al,20h       ;'A'~'Z':41~5AH     ‘a'~'z':61~7ah
            mov dl,al
            mov ah,2
            int 21h
            jmp start
        error:ret
    code ends
         end start

 


3.編寫程序:從鍵盤上接收一個四位數的十進制數,並在終端上顯示出與它等值的二進制數。

        code segment
          assume cs:code
        begin:xor bx,bx       ;清空bx
              mov ch,4
              mov cl,4        ;設置內外層的循環次數
        input:shl bx,cl        ;bx中的內容邏輯左移
              mov ah,1
              int 21h          ;輸入
              cmp al,30h        ;是否小於0
              jb  input         ;是就重新輸入
              cmp al,39h        ;是否大於9
              ja  input     
              and al,0fh        ;轉換為相應的二進制
              jmp combine
             
        combine:or bl,al        
                dec ch
                jnz input
        display:mov cx,16        ;輸出的循環次數
           print:mov dl,0
                 rol bx,1
                 rcl dl,1
                 or dl,30h        ;清空dl
                 mov ah,2
                 int 21h
                 loop print
                 ret
        code ends
             end begin


4.將內存ffff:0~ffff:d單元中的數據復制到0:200~0:20d單元中。

    code segment
     assume cs:code
            mov bx,0
            mov cx,0fh
           
     copy:mov ax,0ffffh   
          mov ds,ax
          mov dl,[bx]
          mov ax,0020h
          mov ds,ax
          mov [bx],dl
          inc bx
          loop copy
         
         
        mov ax,4c00h
        int 21h
    code  ends
            end copy
       
5.將AX寄存器中的16位數分成四組,每組四位,然后把這四組數分別放在AL、BL、CL和DL中。

    data segment
       s db 4 dup(?)   ;占位,並清空
     mov ax,0ffffh
    data ends
    ;-----------------------------------   
     progrnam segment
              assume cs:progrnam,ds:data
     begin:mov cl,4     ;ax邏輯右移四次
           mov ch,4    
           lea bx,s
      X: mov dx,ax
         and dx,0fh      ;邏輯與屏蔽高位
         mov [bx],dl   ;以字節形式將dl移入bx
         inc bx
         shr ax,cl       ;邏輯右移
         dec ch
         jnz X
      Y: mov dl,s        ;依次移入相應寄存器內
         mov cl,s+1
         mov bl,s+2
         mov al,s+3
         ret    
    progrnam ends
        end begin

 

6.從鍵盤輸入一系列字符,以字符‘$’為結束符,然后對其中的非數字字符計數,並顯示出計數結果。

    `stack segment
         dw  100h    dup(?)
         top  label   word
    stack ends
   
    data segment
            h1   db  'Please input a string: ','$'
            h2   db 'The number of the chars that is not digit:','$'
           crlf  db 0dh,0ah,24h
    data   ends
   
    code  segment
          assume  cs:code,ds:data,ss:stack
           
     main  proc    far
      begin:mov     ax,stack
            mov     ss,ax
            lea     sp,top
            mov     ax,data
            mov     ds,ax
   
            lea     dx,h1
        mov    ah,9
        int    21h
   
            mov     cx,0
   
    input:     mov     ah,1
            int     21h
            cmp     al,'$'
            jz      exit
            cmp     al,30h
            jb      count
            cmp     al,39h
            jnb     count
            jmp     input
   
    count:  inc     cx
            jmp     input
   
    exit:   lea     dx,crlf
            mov     ah,9
            int     21h
            lea     dx,h2
            int     21h
   
            mov     si,0
            mov     bl,10
            mov     ax,cx
   
    mem:     div     bl
            mov     dl,ah
            mov     dh,0
            push    dx
            inc     si
            mov     ah,0
            cmp     al,0
            jnz     mem
   
    prin:     pop     dx
            add     dl,30h
            mov     ah,2
            int     21h
            dec     si
            cmp     si,0
            jnz     prin
   
            mov     ah,4ch
            int     21H
   
    main    endp
    code    ends
            end   begin
    `

7.已知兩個整數變量A和B,試編寫完成下述操作的程序:
(1)若兩個數中有一個數是奇數,則將奇數存入A中,偶數存入B中
(2)若兩個數均為奇數,則兩數分別加1,並存回原變量。
(3)若兩個數均為偶數,則兩變量不變。

   
    code segment
         assume cs:code
    begin: mov ax,13
           mov bx,12
           mov cx,ax
           mov dx,bx
           xor ax,bx
           test ax,0001h    ;A和B是否同時為奇數或偶數
           jz next           ;是
           test bx,0001h   
           jz return        ;B為偶數,A為奇數,加1
    exchange:mov ax,dx        ;A為偶數,B為奇數,交換
           mov bx,cx
           jmp return
      next:test bx,0001h    ;是否同為奇數
           jz return        ;同為偶數,不變
           inc dx 
           inc cx
           jmp exchange
      return:ret
    code ends
          end begin

 

8.比較兩個字符串string1和string2所含的字符是否相同。若相同則顯示‘true’,否則顯示‘false’。

     data segment
         string1 db 'i am a student'
         string2 db 'i am a student'
         string3 db 'true',0dh,0ah,'$'
         string4 db 'false',0dh,0ah,'$'
    data ends
    ;--------------------------    
    progrnam  segment
          assume cs:progrnam,ds:data
    start:push ds
          sub ax,ax
          push ax
          mov ax,data
          mov ds,ax
          mov es,ax
    begin:lea si,string1
          lea di,string2
          cld   
          mov cx,string2-string1
          repe cmpsb
          jne Y
          lea dx,string3
          jmp print      
         Y:lea dx,string4
        print: mov ah,9
           int 21h
        mov ax,4c00h
        int 21h
          
    progrnam ends
         end start


   
9.編寫無溢出除法的匯編子程序 。

這里所說的除法溢出並不是指分母為0而發生溢出的情況。我們以除數為8位的情況來說明,假設我們的被除數為65535(16位的最大值)存儲在AX 中,除數為1,存儲在CL中,然后執行除法指令: div CL。根據上面的說法,結果都是放在AX中的,余數為0,當然這沒有問題,然而商為65535要放在AL中卻是放不下的,因為AL能存放的最大值只為 255,所以此時就會發生溢出。我們可以看到65535/1 = 255,這顯然與我位正常的除法結果不符。
如何解決這個溢出問題
既然我們知道了問題的根源,要解 決它就不困難了。為了統一而且不發生溢出,我們可以把所有的除法的商都用32位來保存,即所有的被除數都用32位,所有的除數都用16位,所有的商都用 32位,所有的余數都用16位來保存,就可以解決這個問題,因為一個數除以一個整數后,不可能大於其之前的值。而對於8位的除法,除數和被除數的高位全用 0補全即可。為了達到這個目的,我們就不能使用默認的除法指令div了,而需要我們寫代碼來實現我們自定義的除法。

自定義除法: X為除數,N為被除數,H代表X的高16位,L代表X的低16位,
int(H/N)和rem(H/N)代表着H除以N的商和余數
X/N = int(H/N)* 2^16 + [rem(H/N)* 2^16+L]/N
   
     progrnam segment
              assume cs:progrnam
              mov ax,0ffffh
              mov cx,1           ;初始化進行測試
     begin: cmp cx,0
            je return   ;除數不能為0
            push bx 
            push ax
            mov ax,dx
            mov dx,0
            div cx  ;執行H/N,商保存在ax中,余數在DX中
            mov bx,ax ;把商保存
            pop ax    ;取出低位,執行rem(H/N)*2^16+L
            div cx    ;執行[rem(H/N)*2^16+L]/N ,商保存在ax中 ,余數在dx中
            mov cx,dx ;cx保存余數
            mov dx,bx ;dx中保存高位除法的商
            pop bx
    return:ret
        mov ax,4c00h
        int 21h
    progrnam ends
           end begin

10.編寫一個程序,接受從鍵盤輸入的10個十進制數字,輸入回車符則停止輸入,然后將這些數字加密后(用XLAT指令變換)存入內存緩沖區BUFFER。加密表為:

   輸入數字:0,1,2,3,4,5,6,7,8,9

   密碼數字:7,5,9,1,3,6,8,0,2,4


    data segment
         number db 7,5,9,1,3,6,8,0,2,4
         buffer db 10 dup(?)
    data ends
    ;-------------------------------------
    code segment
         assume cs:code,ds:data
         mov si,0
         mov cx,10
         lea bx,number
    input:mov ah,1
          int 21h
          cmp al,0dh    ;是否為回車符
          jz return
          cmp al,30h    ;比較是否是0~9,不是就重新輸入
          jb input
          cmp al,39h
          ja input
          xlat           ;變換進行存儲
          mov buffer[si],al
          inc si
          loop input
    return:ret
    code ends
    end input
   
    data segment
         number db 7,5,9,1,3,6,8,0,2,4
         buffer db 10 dup(?)
    data ends
    ;-------------------------------------
    code segment
         assume cs:code,ds:data
         mov si,0
         mov cx,10
         lea bx,number
    input:mov ah,1
          int 21h
          cmp al,0dh    ;是否為回車符
          jz return
          cmp al,30h    ;比較是否是0~9,不是就重新輸入
          jb input
          cmp al,39h
          ja input
          xlat           ;變換進行存儲
          mov buffer[si],al
          inc si
          loop input
    return:ret
    code ends
         end input


11.編寫一個子程序嵌套結構的程序模塊,分別從鍵盤輸入姓名及8個字符的電話號碼,並以一定的格式顯示出來。

    主程序TELIST:
    A.    顯示提示符“INPUT  NAME:”;
    B.    調用子程序INPUT_NAME輸入姓名;
    C.    顯示提示符“INPUT  A  TELEPHONE  NUMBER:”;
    D.    調用子程序INPHONE輸入電話號碼;
    E.    調用子程序PRINTLINE顯示姓名及電話號碼。
    子程序INPUT_NAME:
    A.    調用鍵盤輸入子程序GETCHAR,把輸入的姓名存放在INBUF緩沖區中;
    B.    把INBUF中的姓名移入輸出行OUTNAME。
    子程序INPHONE:
    A.    調用鍵盤輸入子程序GETCHAR,把輸入的8位電話號碼存放在INBUF緩沖區中;
    B.    把INBUF中的號碼移入輸出行OUTPHONE。
    子程序PRINTLINE:
    顯示姓名及電話號碼,格式為:
      NAME    TEL.
      X X X        XXXXXXXX

代碼如下:

    data segment
         tipname db 'input name:','$'
         tipnumber db 'input a telephone number:','$'
         inbuf db 12 dup(' ')
         crlf db 0dh,0ah,'$'
         outname db 16 dup(' ')
         outphone db 12 dup(' '),0dh,0ah,'$'
         info db 'name',12 dup(' '),'tel',0dh,0ah,'$'
    data ends
    ;------------------------------------
    stack segment
           dw 100 dup(?)      ;偽定義使得同一個變量具有不同的屬性
        string label word   
    stack ends
    ;----------------------------------------
    progrnam segment
     main proc far
           assume cs:progrnam,ds:data,es:data,ss:stack
      start:mov ax,stack
            mov ss,ax
            mov sp,offset string
            push ds
            xor ax,ax
            push ax
            mov ax,data
            mov ds,ax
            mov es,ax
     
      begin:               
             mov ah,09          ;輸出提示字符串
             mov dx,seg tipname
             mov ds,dx
             mov dx,offset tipname
             int 21h
             call input_name    ;輸入姓名
             mov ah,09           ;輸出提示字符串
             mov dx,seg tipnumber
             mov ds,dx
             mov dx,offset tipnumber
             int 21h
             call input_number
             call printline     
             ret
     main endp
     ;------------------------------------------
     input_name proc near
                call getchar
                lea si,inbuf
                lea di,outname
                mov cx,12      ;設置計數器
                cld             ;設置方向為自增
    ;movsb 與rep結合是傳送字節,相當於 movs es:byte ptr[di],ds:[si]
                rep movsb      
                ret
    input_name endp
    ;-----------------------------------------------
    input_number proc near
             call getchar
             lea si,inbuf
             lea di,outphone
             mov cx,12
             cld
             rep movsb
             ret
    input_number endp
    ;------------------------------------------------
    getchar proc near
            mov al,20h
            mov cx,12 
            lea di,inbuf
            cld
    ;stosb這里是為了每一次輸入一個字節存入相應的緩沖區
            rep stosb
            mov cx,12
            mov di,0
       input:mov ah,1
             int 21h
             cmp al,0dh
             jz return
             mov inbuf[di],al
             inc di
             loop input
        return: call disp_crlf           ;輸出回車符
                ret
    getchar endp
    ;--------------------------------------
    printline proc near             ;這里均是將所得的字符串進行輸出
              mov ah,09
              mov dx,seg info
              mov ds,dx
              mov dx,offset info
              int 21h
              mov ah,09
              mov dx,seg outname
              mov ds,dx
              mov dx,offset outname
              int 21h
              ret
    printline endp
    ;---------------------------------------
    disp_crlf proc near
              mov ah,09
              mov dx,seg crlf
              mov ds,dx
              mov dx,offset crlf
              int 21h
              ret
    disp_crlf endp
    ;-----------------------------------------
    progrnam ends
             end start

12.試編寫一個匯編語言子程序,要求將包含任意字符、以0結尾的字符串中的小寫字母轉換成大寫字母。
   
    data segment
          string db 'i am A stuDEnt',0h
    data ends
    ;------------------------------
   
    progrnam segment
         assume ds:data,cs:progrnam
    start:push ds
         xor ax,ax     
         mov ax,data 
         mov ds,ax
         lea si,string
         push si     
    begin: mov al,[si]      ;判斷是否為小寫字母並進行轉換
          cmp al,0
          je return     
          cmp  al,'a'
          jb print
          cmp  al,'z'
          ja print           ;如果不是小寫字母直接進行輸出
          sub al,20h
          mov [si],al
    print:push ds           ;將字母進行輸出
          ;mov al,[si]
          mov dl,al
          mov ah,2
          int 21h
          pop ds      
        n:inc si
          jmp begin     
    return:
          pop si
          pop ds
        mov ax,4c00h
        int 21h
          
    progrnam ends
        end start 


13.編寫程序,將一個包含有20個數據的數組M分成兩個數組:正數數組P和負數數組N,並分別把這兩個數組中數據的個數顯示出來。   

    data segment
        string1 db 0dh,0ah, 'positive number:','$'
        string2 db 0dh,0ah,'negative number:','$'
        array dw  1,2,3,4,5,6,7,8,-4,-8,-9,-6,-2,-8,8,12,18,-12,5,64
        array1 dw 20 dup(?)     ;存儲正數數組
        array2 dw 20 dup(?)      ;存儲負數數組
        count1 db 0
        count2 db 0               ;計數
        CRLF DB 0dh,0ah,'$'
    data ends
    ;----------------------------------
    progrnam segment
    main proc far
        assume ds:data,cs:progrnam
        s:   push ds
            xor ax,ax
            push ax
            mov ax,data
            mov ds,ax   
        begin:mov cx,20         ;循環次數
              lea bx,array      ;bx相當於數組的首地址
              lea si,array1
              lea di,array2 
        start:mov ax,[bx]
                cmp ax,0         ;是否為負數
                js Y             ;是負數
                mov [si],ax       ;存入正數數組
                inc count1
                add si,2
                jmp short next 
            Y:  mov [di],ax
                inc count2
                add di,2
            next:add bx,2
                 loop start
            lea dx,string1
            mov al,count1
            call print
            lea dx,string2
            mov al,count2        
            call print
            ret
    main endp         
    ;--------------------------------------
    print  proc near
            push ax      ;al中存儲計數值,要進行保存
            mov ah,9
            int 21h
            pop ax        ;出棧,進行ASCII碼調整
            aam            ;調整方式AH<-AL/10(商),AL<-AL%10
            push ax 
            add ah,30h    ;變為0~9的ASCII碼
            mov dl,ah
            mov ah,2
            int 21h
            pop ax
            add al,30h
            mov dl,al
            mov ah,2
            int 21h
            lea dx,CRLF
            mov ah,9
            int 21h
            ret
    print endp
    progrnam ends
            end s

14.設有10個學生的成績分別是76,69,84,90,73,88,99,63,100和80分。試編制一個子程序統計60~69分,70~79分,80~89分,90~99分和100分的人數,分別存放到S6,S7,S8,S9和S10單元中。


    data segment
         grade dw 76,69,84,90,73,88,99,63,100,80
         count1 dw 0
         count2 dw 0
         count3 dw 0
         count4 dw 0
         count5 dw 0
    data ends
    ;-----------------------------------------
    progrnam segment
             assume ds:data,cs:progrnam
              push ds
              xor ax,ax
              push ax
              mov ax,data
              mov ds,ax
        begin:mov cx,10
        mov si,0
        next:mov ax,grade[si]
             mov bx,10
             div bl
             mov bl,al
             sub bx,6
             sal bx,1    ;將(grade/10-6)×2就是
             inc count1[bx]  ;count1是首地址
             add si,2
        loop next
    progrnam ends
         end begin

15.輸出空行


    progrnam segment
             assume cs:progrnam
        begin:push cx
              push dx
              mov ax,3    ;這里對ax進行賦值,觀察輸出的結果
              mov cx,ax
        print:mov dl,0dh
              mov ah,2    ;這是對與輸出一個字符的bios的調用
              int 21h  ;print的功能就是輸出空行,0dh為回車
            mov dl,0ah ;0ah為換行
            mov ah,2
            int 21h   
            loop print
            pop dx
            pop cx
        ;這一段程序是為了測試輸出后的結果,主要母的是輸出一個黃色的'*'
            mov ah,9
            mov al,'*'
            mov bh,0
            mov bl,0eh
            mov cx,1
            int 10h
            ret
    progrnam ends
             end begin


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM