彙編程序 - 1 (32位無符號乘法)

這個是學校的課程設計《微機原理與接口技術》內容,本身寫得有些缺陷,但基本實現了運算功能,暫且記錄,方便往後回顧,也供你們參考。工具

缺陷:spa

1. 只能固定長度輸入(32位對應爲00000000 -- FFFFFFFF)設計

2. 例如輸入6(16進制)只能相似輸入00000006調試

3.只考慮了0-F中的0-9輸入,也沒考慮A-F或者a-fcode

暫時沒空修改,之後有空或許會再寫寫blog

 

實驗環境:接口

1.我是在虛擬機上的Windows 7 調試的,TD調試中顯示的cpu是80486,但本次實驗要求所用8086(16位),這個沒影響,由於80486指令集的向前兼容,只要咱們寫的8086的指令就行。內存

  說明這個的緣由在於,80486已經有新的指令集了,直接能夠進行32位運算。虛擬機

2. ......沒了  >==< !asm

 

設計思路:

輸入:

輸入時,由於調用INT 21(01H)進行輸入,而該功能調用只能每次輸入一個字符,且存入AL中的數據爲其ASCII值,因此,首先要對輸入的值進行轉換成真實數據,同時加循環能夠完成對固定長度數據的輸入。

運算:

運算時,因爲在16位寄存器的8086系統中,一次性只能對16位的數據進行運算,故當咱們須要對其進行32位運算時,考慮分段進行,每次分段的結果數據(DX:AX)都放在內存相對應地址中(標號爲HH、HL、LH、LL)。以32位長度的數據DX:AX兩個數據相乘舉例,數據分爲高位(H)和低位(L),則分段相乘能夠分爲L-L,L-H,H-L,H-H相乘(L、H表明32位數據的高位數據和低位數據),其中每一個相乘的值都放在DX:AX中。在L-L中,L-L->AX因爲是乘積的最低位,且MUL指令無溢出狀況,故無需考慮進位;在L-L->DX和L-H->AX和H-L->AX之和中,須要考慮向高位進位的狀況,可使用PUSHF將標誌寄存器的狀態入棧,在高位使用ADC指令便可;L-H->DX和H-L->DX和H-H->AX之和中,須要同時考慮向高位的進位和低位的進位值,處理方法同前;H-H->DX爲乘積的最高位,只需考慮低位的進位。

輸出:

輸出時,要考慮運算後的數據和輸出的數據,即運算後的數據爲乘積的真值,而輸出的數據是字符所對應的ASCII值。同時爲了考慮美觀性,前置的0考慮將其去除,加判斷跳轉語句可實現。具體實現是,先判斷取出的BX是否爲0,爲0則表明該數據不用輸出,程序跳轉到執行下一個地址處理;當取出的數據可能存在開始數據爲0100/0A11和非開始數據爲0100/0A11的狀況。即最開始的0是不用輸出的,可是除了最開始的0不輸出外,其餘的0是真值,須要輸出。考慮設計一個標誌實現,本設計用SI實現,初始值爲0H,當輸出一個真值以後,將其值變爲01H,以後同時判斷SI和要輸出的值,當輸出值爲0且SI爲01H時,即該數據爲真值,須要輸出。

代碼:

//mul.asm
DATA        SEGMENT
            BUF1 DB 0DH,0AH,'PLEASE INPUT NUM_1(00000000-99999999):',0DH,0AH,'$'
            BUF2 DB 0DH,0AH,'PLEASE INPUT NUM_2(00000000-99999999):',0DH,0AH,'$'
            BUF3 DB 0DH,0AH,'THE RESULT IS:',0DH,0AH,'$'
            ;作成任意輸入的
            NUM1        DW        2 DUP(?)
            NUM2        DW        2 DUP(?)
            HL            DW        2 DUP(?)
            HH            DW        2 DUP(?)
            LH            DW        2 DUP(?)
            LL            DW        2 DUP(?)
            SUM            DW        4 DUP(?)
DATA        ENDS

CODE        SEGMENT
MAIN        PROC    NEAR
            ASSUME    CS:CODE,DS:DATA
START:        
IN_TIPS:
            MOV        BX,DATA
            MOV        DS,BX            
IN_1:
            LEA        DX,BUF1
            MOV        AH,09H
            INT        21H
            LEA        BX,NUM1
            CALL    INPUT
IN_2:
            LEA        DX,BUF2
            MOV        AH,09H
            INT        21H
            LEA        BX,NUM2
            ;ADD        BX,3
            CALL    INPUT
;TAKEMUL
            CALL    TAKEMUL
;OUTPUT                    
            CALL    OUTPUT
;END
            MOV        AH,4CH
            INT        21H
            RET
MAIN        ENDP

INPUT        PROC    NEAR
            MOV        DX,2
INNUM:        
            ;1(5)->Input Number
            MOV        AH,01H
            INT        21H
            SUB        AL,30H    
            MOV        CL,4
            SHL        AL,CL
            MOV        CL,AL
            ;2(6)->Input Number
            MOV        AH,01H
            INT        21H
            SUB        AL,30H
            ADD        CL,AL
            PUSH    CX
            ;3(7)->Input Number
            MOV        AH,01H
            INT        21H
            SUB        AL,30H
            MOV        CL,4
            SHL        AL,CL
            MOV        CH,AL
            ;4(8)->Input Number
            MOV        AH,01H
            INT        21H
            SUB        AL,30H
            ADD        CH,AL
            MOV        AL,CH
            ;SEND To MEMORY
            POP        CX
            MOV        AH,CL
            MOV        [BX],AX
            ADD        BX,2
            DEC        DX
            JNZ        INNUM
            RET
INPUT        ENDP

TAKEMUL        PROC    NEAR
            LEA        SI,NUM1
            LEA        DI,NUM2
H_L:        ;<<16
            MOV        AX,[SI]
            ADD        DI,2
            MUL        WORD PTR[DI]
            LEA        BX,HL
            MOV        [BX],DX
            ADD        BX,2;WORD
            MOV        [BX],AX
            ADD        BX,2
H_H:        ;<<32
            MOV        AX,[SI]
            SUB        DI,2            
            MUL        WORD PTR[DI]
            LEA        BX,HH
            MOV        [BX],DX
            ADD        BX,2
            MOV        [BX],AX
            ADD        BX,2
L_H:        ;<<16
            ADD        SI,2
            MOV        AX,[SI]
            MUL        WORD PTR[DI]
            LEA        BX,LH
            MOV        [BX],DX
            ADD        BX,2
            MOV        [BX],AX
            ADD        BX,2
L_L:        ;<<0
            MOV        AX,[SI]            
            ADD        DI,2
            MUL        WORD PTR[DI]
            LEA        BX,LL
            MOV        [BX],DX
            ADD        BX,2
            MOV        [BX],AX    
            ADD        BX,2            
TAKE:        
            ;L-L:
            ;LL->AX:32位X32位運算數據的最低位
            LEA        DI,LL
            ADD        DI,2
            MOV        AX,[DI]
            LEA        BX,SUM
            MOV        [BX],AX
            ADD        BX,2
            ;LL->DX:LL->DX + LH->AX + HL->AX
            LEA        DI,LL
            MOV        AX,[DI]
            MOV        [BX],AX
            ;ADD        BX,2            
            ;HL+LH
            ;HL->AX+LH->AX
            LEA        DI,HL
            ADD        DI,2
            MOV        AX,[DI]
            LEA        DI,LH
            ADD        DI,2
            ADD        AX,[DI]
            PUSHF
            ADD        AX,[BX];LL->DX            
            MOV        [BX],AX
            ADD        BX,2    
            ;HL->DX+LH->DX (CF)
            LEA        DI,HL
            MOV        AX,[DI]
            LEA        DI,LH
            POPF
            ADC        AX,[DI]
            PUSHF
            MOV        [BX],AX            
            ;HH(CF)
            ;HH->AX
            LEA        DI,HH
            ADD        DI,2
            MOV        AX,[DI]
            POPF
            ADC        AX,[BX];HL->DX+LH->DX
            MOV        [BX],AX
            ADD        BX,2
            ;HH->DX
            LEA        DI,HH
            MOV        AX,[DI]
            ADC        AX,0H
            MOV        [BX],AX
            ADD        BX,2
            RET
TAKEMUL        ENDP

OUTPUT        PROC    NEAR
            LEA        DX,BUF3
            MOV        AH,09H
            INT        21H
            LEA        DI,SUM
            ADD        DI,7
            MOV        CX,8
            MOV        SI,0H;RE_COMPARE
ADJUST:        
            MOV        BL,[DI]
            MOV        BH,BL
            AND        BX,0F00FH
            PUSH    CX
            CMP        BX,0H
            JE        ZERO            
            MOV        CL,4
            SHR        BH,CL
            MOV        DL,BH
            CALL    COMPARE
            MOV        DL,BL
            CALL    COMPARE
ZERO:        
            DEC        DI
            POP        CX
            LOOP    ADJUST
            RET
OUTPUT        ENDP

COMPARE        PROC    NEAR
            CMP        DL,0AH
            JAE        OUT_ENG;JNB
            CMP        DL,00H
            JE        RE_COMPARE
            JA        OUT_NUM
            JMP        COMPARE_END
RE_COMPARE:
            CMP        SI,0H
            JE        COMPARE_END
            JNE        OUT_NUM
OUT_ENG:    
            ADD        DL,37H;ACSII->A-0AH
            MOV        AH,02H
            INT        21H
            MOV        SI,01H
            JMP        COMPARE_END
OUT_NUM:    
            ADD        DL,30H
            MOV        AH,02H
            INT        21H
            MOV        SI,01H
COMPARE_END:
            RET
COMPARE        ENDP

CODE        ENDS
            END        START

因爲分析中解釋清楚了,加上代碼命名相對比較見名知意,因此沒註釋(極少),以後會上傳一個TD工具下的調試Blog,我以爲這個會更有用!!!

 

放兩張截圖吧 ~__~

說明:輸入,輸出都爲16進制數,爲何是16進制?由於寄存器裏面存的的就是16進制啊,我又不傻,直接輸出就好,幹嗎轉換啊。哈哈哈哈哈哈@__@,機智!!!

 

驗證說明:驗證數據經過計算器得出結果。

驗證1:12345678H * 12345678H = 14B 66DC 1DF4 D840H

驗證2:99999999H * 99999999H = 5C28 F5C1 D70A 3D71H

驗證3:6H * 6 H = 24H

 

嗯~ o(* ̄▽ ̄*)o,基本上就這樣了!歡迎參考,若是你寫了更完整的,歡迎留言提供連接。

相關文章
相關標籤/搜索