#99 Article 963 Posted at 1995/12/03 06:15:00 by MSP-Iris (MAP4370) [SAHOU]

Subject: Re:*7 プログラミングお作法の話 /948 ... /941 /940

次いでアセンブラ。
 アセンブル:TASM Ver2.0 nyana.com 336bytes

 こちらはコマンドラインから入力する方式で、これも数値は999までに
限定してあります(4桁以上入力すると頭3桁が有効)。また、数字を画面
表示する時、3桁ノンゼロサプレスになっています。

 途中'sub ax,1'というのがありますが、これは'dec ax'だとキャリーが立
たないためです。余談ですが、'dec''inc'でキャリーが動かないというのは
プロでもうっかりするもののようです。業務用ゲーム「グラディウス2」で
は残機が100機になるとその時点でゲームオーバーとなりますが、これは
この点が原因です(残機を'inc'した後、BCDで3桁になったかをキャリー
で調べているそうです)。
----------------------------------------
cr      equ     0dh
lf      equ     0ah
true = ( 0 eq 0 )
false= ( 0 eq 1 )

.186
locals __
assume  cs:code,ds:code,ss:code

PRTMSG  macro X
        mov ah,09
        mov dx,offset &X
        int 21h
endm

RETDOS  macro
        mov ax,4c00h
        int 21h
endm

code    segment
        org 100h

start:  jmp start2

SC3KETA proc                    ;IN  SI=offset parami,DI=offset param
                                ;OUT to param
        pusha
        lodsb
        mov dh,al
        lodsb
        cmp al,-1
        jne __2or3keta
__1keta:                        ;DH*1
        mov al,dh
        xor ah,ah
        mov [di],ax
        popa
        ret
__2or3keta:
        mov dl,al
        lodsb
        cmp al,-1
        jne __3keta
__2keta:                        ;DH*10+DL*1
        mov al,10
        mul dh
        xor dh,dh
        add ax,dx
        mov [di],ax
        popa
        ret
__3keta:                        ;DH*100+DL*10+CL*1
        mov cl,al
        mov al,10
        mul dl
        xor ch,ch
        add cx,ax
        mov ax,100
        mov bl,dh
        xor bh,bh
        mul bx
        add ax,cx
        mov [di],ax
        popa
        ret
endp

PR3KETA proc                    ;IN  AX=num,SI=offset nummsg
                                ;OUT to nummsg
        push ax
        mov [si],'00'
        mov byte ptr [si+2],'0'
__cp100:sub ax,100
        jc __ud100
        inc byte ptr [si]
        jmp short __cp100
__ud100:add ax,100
__cp010:sub ax,10
        jc __ud010
        inc byte ptr [si+1]
        jmp short __cp010
__ud010:add ax,10
__cp001:sub ax,1
        jc __ud001
        inc byte ptr [si+2]
        jmp short __cp001
__ud001:pop ax
        ret
endp

start2: mov ax,cs
        mov es,ax
        mov si,0081h            ;ds=PSP by MS-DOS
        mov di,offset parami
        cld
__next: lodsb
        cmp al,cr
        je eopara
        cmp al,' '
        je __next
        sub al,'0'
        stosb
        cmp di,offset parami+3
        je eopara
        jmp short __next

eopara: mov ax,cs
        mov ds,ax
        mov si,offset parami
        mov di,offset param
        cmp byte ptr [si],-1
        je abort
        call SC3KETA
        mov ax,param
        and ax,ax
        jnz gonyan

abort:  PRTMSG  abmsg
        mov ax,4c01h
        int 21h

gonyan: xor ax,ax
        mov si,offset nummsg
ncount: inc ax
        push ax
        cmp ax,3
        je pnyan3
        cmp ax,5
        je pnyan5
        cmp ax,param
        je eocount

        call PR3KETA
        PRTMSG  nummsg
        pop ax
        jmp short ncount

pnyan5: irp Y,<nyanmsg,nyanmsg>
        PRTMSG  &Y
endm
pnyan3: irp Y,<nyanmsg,nyanmsg,nyanmsg,nlmsg>
        PRTMSG  &Y
endm
        pop ax
        cmp ax,param
        jne ncount
        RETDOS

eocount:pop ax
        mov cx,ax
__eoc2: PRTMSG  nyanmsg
        loop __eoc2
        PRTMSG  nlmsg
        RETDOS

parami  db      -1,-1,-1
nlmsg   db      cr,lf,'$'
nummsg  db      '000',cr,lf,'$'
abmsg   db      'Abnormal terminated.',cr,lf,'$'
nyanmsg db      'にゃん$'
even
param   dw      0

ends
end start
----------------------------------------
                                  MAP4370    MSP-Iris