#99 Article 1013 Posted at 1995/12/11 00:00:55 by MSP-Iris (MAP4370) [SAHOU.2]

Subject: Re: プログラミング作法・お題2 /995

アセンブラ版です。行数はありますが、実行ファイルは400バイト。
 基本的な考え方はC版と同じです。1論理行内の文字数制限無し。
 問題の検索ルーチンは Boyer-Moore 法...のつもり。(^^;
--------------------------------
cr      equ     0dh
lf      equ     0ah
true = ( 0 eq 0 )
false= ( 0 eq 1 )

RBYTE   equ     1024

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

FOP     macro FNAME
        mov dx,offset &FNAME
        mov al,2
        mov ah,3dh
        int 21h
endm

FRD     macro HANDLE,BYTE,BUF
        mov dx,offset &BUF
        mov cx,&BYTE
        mov bx,&HANDLE
        mov ah,3fh
        int 21h
endm

FCL     macro HANDLE
        mov bx,&HANDLE
        mov ah,3eh
        int 21h
endm

FSK     macro HANDLE,SEEKDIST,MODE
        mov dx,&SEEKDIST
        mov cx,&SEEKDIST[2]
        mov bx,&HANDLE
        mov al,&MODE
        mov ah,42h
        int 21h
endm

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

RETDOS  macro
        mov ax,4c00h
        int 21h
endm

code    segment
        org 100h

start:  jmp start2

PR5KETA proc                    ;IN  AX=num,SI=offset nummsg
                                ;OUT to nummsg
        push ax
        push si

        irp Y,<10000,1000,100,10,1>
        mov byte ptr [si],'0'
__cp&Y: sub ax,&Y
        jc __ud&Y
        inc byte ptr [si]
        jmp short __cp&Y
__ud&Y: add ax,&Y
        inc si
endm
        pop si
        pop ax
        ret
endp

BMSRCH  proc
        pusha                   ;needs: buffer,SWORD,SLENG,
        mov si,offset buffer    ;       worka,workb,sflag
        mov di,offset SWORD     ;       counter,srchb
__cmploop:
        mov sflag,0
        mov worka,1
        mov workb,1
__cmpmain:
        mov bx,SLENG
        sub bx,worka
        mov al,[si+bx]
        mov bx,SLENG
        sub bx,workb
        cmp al,[di+bx]
        je __cmphit
__cmpnothit:
        mov sflag,1
        mov ax,workb
        cmp ax,SLENG
        je __eonohit
        inc workb
        jmp __cmpmain
__eonohit:
        mov ax,workb
        sub ax,worka
        inc ax
        jmp __shiftbase
__cmphit:
        cmp sflag,0
        je __keephitting
        mov ax,workb
        sub ax,worka
        jmp __shiftbase
__keephitting:
        mov ax,worka
        cmp ax,SLENG
        je __hitall
        inc worka
        inc workb
        jmp __cmpmain
__hitall:
        inc counter
        mov ax,SLENG
__shiftbase:
        add si,ax
        mov ax,offset buffer
        add ax,srchb
        sub ax,SLENG
        cmp si,ax
        ja __eothisseq
        jmp __cmploop
__eothisseq:
        popa
        ret
endp

start2: FOP     SFILE
        jnc __canopen
        PRTMSG  errmsg1
        mov ax,4c01h
        int 21h
__canopen:
        mov fhandle,ax
        xor ax,ax
        sub ax,SLENG
        inc ax
        mov seekdis,ax
        mov ax,-1
        mov seekdis[2],ax
__fileread:
        FRD     fhandle,RBYTE,buffer
        mov readb,ax
        and ax,ax
        jnz __notend
        mov si,offset cntmsg
        mov ax,counter
        call PR5KETA
        PRTMSG  cntmsg
        FCL     fhandle
        RETDOS

__notend:
        mov ax,readb
        mov srchb,ax
        call BMSRCH

        mov ax,readb
        cmp ax,SLENG
        jb __mustnotseek
        FSK     fhandle,seekdis,1
__mustnotseek:
        jmp __fileread

SFILE   db      'LOG',0
SWORD   db      'MAPLE',0
cntmsg  db      '00000maples here.',cr,lf,'$'
errmsg1 db      'Cannot open LOG.',cr,lf,'$'
sflag   db      0
even
SLENG   dw      5
counter dw      0
readb   dw      ?
srchb   dw      ?
fhandle dw      ?
seekdis dw      ?
        dw      ?
worka   dw      ?
workb   dw      ?
buffer  db      RBYTE dup(?)

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