FizzBuzz問題の解答例 MASM編

MASM (Microsoft Macro Assembler)によるFizzBuzz問題の解答例。

解答例

条件分岐とループによるプログラム:

COMMENT $
  fizzbuzz.asm
  MASM32でコンパイル(EXE形式)
$

CODE    SEGMENT
        ASSUME  cs:CODE,ds:DATA,ss:STK
START:
        mov     ax,DATA
        mov     ds,ax

        mov     cx,1
MAIN_LP:
        cmp     cx,100   ; while cx <= 100
        jg      END_MAIN_LP
; cxが3の倍数かつ5の倍数のとき
        mov     ax,cx
        mov     dx,0     ; 16ビット符号なし除算を行う
        mov     bx,3     ; DX:AX = BX * AX + DX
        div     bx
        cmp     dx,0
        jne     ELS_IF1
        mov     ax,cx
        mov     dx,0     ; 16ビット符号なし除算を行う
        mov     bx,5     ; DX:AX = BX * AX + DX
        div     bx
        cmp     dx,0
        jne     ELS_IF1
        mov     ah,09H
        mov     dx,OFFSET FZBZ
        int     21H
        call    CR_LF
        jmp     IF_END
ELS_IF1:  ; cxが3の倍数(かつ5の倍数でない)とき
        mov     ax,cx
        mov     dx,0     ; 16ビット符号なし除算を行う
        mov     bx,3     ; DX:AX = BX * AX + DX
        div     bx
        cmp     dx,0
        jne     ELS_IF2
        mov     ah,09H
        mov     dx,OFFSET FIZZ
        int     21H
        call    CR_LF
        jmp     IF_END
ELS_IF2:  ; cxが5の倍数(かつ3の倍数でない)とき
        mov     ax,cx
        mov     dx,0     ; 16ビット符号なし除算を行う
        mov     bx,5     ; DX:AX = BX * AX + DX
        div     bx
        cmp     dx,0
        jne     ELS_LAST
        mov     ah,09H
        mov     dx,OFFSET BUZZ
        int     21H
        call    CR_LF
        jmp     IF_END
ELS_LAST:  ; cxが3の倍数でも5の倍数でもないとき
        push    cx  ; CXの値を退避
        mov     ax,cx
        call    PUTD_AX
        pop     cx  ; CXの値を復元
        call    CR_LF
IF_END:
        inc     cx
        jmp     MAIN_LP
END_MAIN_LP:

        mov     ah,4CH
        int     21H

; サブルーチン

; 改行の表示
CR_LF:
        mov     ah,02H
        mov     dl,13  ; CR
        int     21H
        mov     dl,10  ; LF
        int     21H
        ret

; レジスタ値の表示
; mov ax,100
; call PUTD_AX => 100と表示
PUTD_AX PROC
        mov     cx,5  ; 5桁の10進数整数を扱う
PUTD_LP1:
        mov     bx,10
        mov     dx,0  ; 16ビット符号なし除算を行う
        div     bx    ; DX:AX = BX * AX + DX
        push    dx    ; 1桁ずつ格納する
        loop    PUTD_LP1

        mov     cx,5  ; 5桁の10進数整数を扱う
        mov     bx,0  ; 先行の0を判定
PUTD_LP2:
        pop     dx     ; 1桁ずつ取り出す
        cmp     cx,1   ; 1桁目は必ず表示
        je      PUTD_SKIP1
        add     bx,dx  ; DXが0のままならばBXも0のまま
        cmp     bx,0   ; 先行の0は表示しない
        je      PUTD_SKIP2
PUTD_SKIP1:
        mov     ah,02H  ; 1桁分だけ表示する
        add     dl,48   ; 数値をASCIIコードに変換('0'=48)
        int     21H
PUTD_SKIP2:
        loop    PUTD_LP2
        ret
PUTD_AX ENDP

CODE    ENDS

DATA    SEGMENT
FZBZ    DB      "Fizz,Buzz",'$'
FIZZ    DB      "Fizz",'$'
BUZZ    DB      "Buzz",'$'
DATA    ENDS

STK     SEGMENT STACK
        DB      100H DUP(?)
STK     ENDS

        END     START

【theme : プログラミング
【genre : コンピュータ

プロフィール

よしいず

Author:よしいず
MATHEMATICS.PDFというウェブサイトを運営しています。

管理の都合上、トラックバックとコメントはオフにしてあります。ブログ経験者なら分かっていただけると思いますが、スパム(アダルトやその他の宣伝)ばかりなのが現実です。

リンクは自由です。当サイトの記事に対する間違いの指摘・意見・感想などを述べた記事からのリンクは歓迎です。ただし、ブログ記事アップ直後はミスが多く、頻繁に修正します。場合によっては削除する可能性もあります。その際、何も断りもなく修正・削除しますがご了承ください。内容を参考にする場合には投稿後一週間ほど様子を見てからにしてください(笑)。

記事の間違いを指摘するときは、その具体的箇所、理由(仕様に反するなど)・根拠(参考にした文献など)、代替案(同じ結果を得るための正しいやり方)も教えてください。そうしないと、(指摘される側および第三者はその時点では無知の状態なので、)どこが間違いなのか分かりませんし、本当に間違っているのかどうかが判断・検証できません。実際、間違いだと指摘されたことが結局は正しかったというケースもありますので。

このブログのタイトル一覧

リンク
月別アーカイブ
カテゴリ
最新記事
検索フォーム
RSSリンクの表示