技術者のためのアセンブリ言語による乗算、除算


乗算

;***********************************
;* #FFFF * 100 = #63FF9C
;***********************************
MAIN    START
        LAD     GR2,#FFFF
        LAD     GR3,100
        CALL    MUL32
        RET
;***********************************
; 乗算
;* GR1, GR2 <-- GR2 * GR3 
;***********************************
MUL32   START
        LAD     GR7,16
        LAD     GR1,0           ; GR1を0に初期化する
;
LOOP    LD      GR6,GR2         ; GR2のLSBが立っていたら、GR1にGR3を加える
        AND     GR6,=#0001
        JNZ     LSBON1
        JUMP    CONT1
;
LSBON1  ADDL    GR1,GR3
;       JUMP    CONT1
;
CONT1   SRL     GR1,1           ; GR1とGR2をひとつのビット列とみなして、右シフトする
        JOV     LSBON2
;
        LAD     GR4,#0000
        JUMP    CONT2
;
LSBON2  LAD     GR4,#8000
;       JUMP    CONT2
;
CONT2   SRL     GR2,1
        OR      GR2,GR4
;
        SUBL    GR7,=1          ; 1ワード(16ビット)分、繰り返したか?
        JNZ     LOOP            ; いいえ(ループを継続する)
;
        RET
        END

除算

;***********************************
; 除算
; 6553500(#63FF9C) ÷ 123  =  53280(#D020) --- 60(#3C)
;***********************************
MAIN    START
        LAD     GR1,#0063   ; 被除数を格納する
        LAD     GR2,#FF9C
        LAD     GR3,123     ; 除数を格納する
        CALL    DIV32
        RET
;***********************************
; GR1:余り,GR2:商 <-- GR1,GR2 ÷ GR3 
;***********************************
DIV32   LAD     GR7,16
;
LOOP    CPL     GR1,GR3     ; GR1はGR3未満か?
        JMI     MINUS       ; はい
;
        SUBL    GR1,GR3     ; GR1がGR3以上ならば、①GR1からGR3を引き、
        LAD     GR5,#0001   ; ②GR1とGR2をひとつにして左に1ビットシフトし、
        JUMP    CONT1       ; LSBに1をセットする
;
MINUS   LAD     GR5,#0000   ; GR1がGR3未満ならば、
;       JUMP    CONTI1      ; GR1とGR2をひとつにして左に1ビットシフトし、LSBに0をセットする
;
CONT1   SLL     GR2,1
        JOV     MSBON
;
        LAD     GR6,#0000
        JUMP    CONT2
;
MSBON   LAD     GR6,#0001
;       JUMP    CONT2
;
CONT2   OR      GR2,GR5
;
        SUBL    GR7,=1      ; 1ワード(16ビット)分、繰り返したか?
        JMI     FIN         ; はい(終了する)
;           
        SLL     GR1,1
        OR      GR1,GR6
;
        JUMP    LOOP
;
FIN     RET
        END