📄 tskprf.asm
字号:
; Exit: BX = converted length
; SS:DI = string start + 1
; Uses: CX
;
@binconv proc near
xor bx,bx
mov cx,16
bclp:
push ax
and al,1
add al,'0'
mov byte ptr ss:[di],al
inc di
inc bx
pop ax
shr ax,1
jz bcend
loop bclp
;
bcend:
ret
;
@binconv endp
;
;
; decconv - convert decimal
;
; Entry: DX,AX = number
; SS:DI = Buffer top pointer
; Exit: BX = converted length
; SS:DI = string start + 1
; Uses: CX
;
@decconv proc near
xor bx,bx
mov cx,10
or dx,dx
jnz dchiword
;
dclp1:
xor dx,dx
div cx
add dl,'0'
mov byte ptr ss:[di],dl
inc di
inc bx
or ax,ax
jnz dclp1
ret
;
dchiword:
push si
mov si,dx
;
dchilp:
xchg ax,si
xor dx,dx
div cx
xchg ax,si
div cx
add dl,'0'
mov byte ptr ss:[di],dl
inc di
inc bx
or si,si
jnz dchilp
;
pop si
jmp dclp1
;
@decconv endp
;
;
; getint - read integer at DS:SI
; Entry: AL = first char
; Exit: AX = integer
; Uses: BX,DX
;
@getint proc near
;
and ax,0fh
mov bl,10
getintlp:
xchg ax,dx
lodsb
cmp al,'0'
jb getint_end
cmp al,'9'
ja getint_end
and ax,0fh
xchg ax,dx
mul bl
add ax,dx
jmp getintlp
;
getint_end:
dec si
mov ax,dx
ret
;
@getint endp
;
;
; padleft - local routine to pad output on the left side.
;
@padleft proc near
;
push cx
push dx
xor dx,dx
test prflags[bp],F_PREC
jz padleft_noprec
cmp bx,prec[bp]
jae padleft_noprec
;
mov dx,prec[bp]
sub dx,bx
test prflags[bp],F_WIDTH
jz padleft_noprec
sub prwidth[bp],dx
jnc padleft_noprec
and prflags[bp],NOT F_WIDTH
;
padleft_noprec:
test prflags[bp],F_LEFTADJ
jnz padleft_end
test prflags[bp],F_WIDTH
jz padleft_end
cmp bx,prwidth[bp]
jae padleft_end
;
mov cx,prwidth[bp]
sub cx,bx
add procnt[bp],cx
mov al,' '
test prflags[bp],F_PADZERO
jz padleftlp
mov al,'0'
;
padleftlp:
push ax
call prproc[bp]
pop ax
loop padleftlp
;
padleft_end:
mov cx,dx
jcxz padleft_exit
add procnt[bp],cx
;
padleftprec:
mov al,'0'
call prproc[bp]
loop padleftprec
;
padleft_exit:
pop dx
pop cx
ret
;
@padleft endp
;
; padright - local routine to pad output on the right side
;
@padright proc near
;
test prflags[bp],F_LEFTADJ
jz padright_end
test prflags[bp],F_WIDTH
jz padright_end
cmp bx,prwidth[bp]
jae padright_end
;
push cx
mov cx,prwidth[bp]
sub cx,bx
add procnt[bp],cx
;
padrightlp:
mov al,' '
call prproc[bp]
loop padrightlp
pop cx
;
padright_end:
ret
;
@padright endp
;
;
; disprintf: display formatted string.
;
; Entry: DS:SI = format string
; ES:DI = parameter pointer
; CX = output routine address
; BX,DX = output routine parameter
;
; Uses: AX,BX,DX
;
; Usually, the parameter pointer will point to the first
; parameter on the stack. For added flexibility, ES:DI is
; used here, so that the parameter list may be anywhere in
; memory. This allows vprintf-style parameters.
;
;
@disprintf proc near
push bp
sub sp,TYPE dislocrec
mov bp,sp
mov prproc[bp],cx
mov prargbx[bp],bx
mov prargdx[bp],dx
mov procnt[bp],0
;
disploop:
lodsb
or al,al
jz dispend ; end of string
cmp al,'%'
je dispformat ; jump if format character
cmp al,0ah
jne dispchar
mov al,0dh
call prproc[bp] ; translate LF into CR+LF
inc procnt[bp]
mov al,0ah
;
dispchar:
call prproc[bp]
inc procnt[bp]
jmp disploop
;
dispend:
mov bx,prargbx[bp]
add sp,TYPE dislocrec
pop bp
ret
;
disploop1:
pop di
pop es
add di,arglen[bp]
jmp disploop
;
; Format character found, process conversion
;
dispformat:
lodsb
cmp al,'%' ; %% means print single %
je dispchar
;
push es
push di ; save parameter pointer
mov prflags[bp],0
mov arglen[bp],2
;
cmp al,'-'
jne no_flags
or prflags[bp],F_LEFTADJ
lodsb
;
no_flags:
cmp al,'0'
jne no_zero
or prflags[bp],F_PADZERO
lodsb
;
no_zero:
cmp al,'*'
je loadwidth
cmp al,'9'
ja no_width
cmp al,'0'
jb no_width
call @getint
jmp short haswidth
;
loadwidth:
mov ax,word ptr es:[di]
add di,2
add arglen[bp],2
;
haswidth:
or prflags[bp],F_WIDTH
mov prwidth[bp],ax
lodsb
;
no_width:
cmp al,'.'
jne no_prec
lodsb
cmp al,'*'
je loadprec
cmp al,'9'
ja no_prec
cmp al,'0'
jb no_prec
call @getint
jmp short hasprec
;
loadprec:
mov ax,word ptr es:[di]
add di,2
add arglen[bp],2
;
hasprec:
or prflags[bp],F_PREC
mov prec[bp],ax
lodsb
;
; Process indirection.
;
no_prec:
mov dx,ds
cmp al,'^'
je indir_near
cmp al,'@'
jne no_indir
add arglen[bp],2
;
indir_near:
or prflags[bp],F_INDIR
;
indir_loop:
cmp al,'^'
je is_indir
cmp al,'@'
jne no_indir
mov dx,word ptr es:2[di]
is_indir:
mov di,word ptr es:[di]
mov es,dx
lodsb ; next conversion char
jmp indir_loop
;
; Indirection finished, check for size modification
;
no_indir:
IF DFLT_FAR
cmp al,'s'
je dfltsize0
cmp al,'n'
je dfltsize0
cmp al,'p'
je dfltsize0
cmp al,'P'
jne dfltsize1
;
dfltsize0:
or prflags[bp],F_LONGARG
jmp short no_sizemod
;
dfltsize1:
ENDIF
cmp al,'F'
je sizemodl
cmp al,'N'
jne sizemod2
lodsb
jmp short no_sizemod
;
sizemod2:
cmp al,'h'
je sizemod2a
cmp al,'H'
jne sizemod3
dec arglen[bp]
sizemod2a:
or prflags[bp],F_SHORTARG
lodsb
jmp short no_sizemod
;
sizemod3:
cmp al,'l'
jne no_sizemod
;
sizemodl:
or prflags[bp],F_LONGARG
lodsb
;
no_sizemod:
xor dx,dx
test prflags[bp],F_LONGARG
jz loadsingle
mov dx,word ptr es:2[di]
test prflags[bp],F_INDIR
jnz loadsingle
add arglen[bp],2
;
loadsingle:
mov bl,al
mov ax,word ptr es:[di]
test prflags[bp],F_SHORTARG
jz noshort
xor ah,ah
;
noshort:
cmp bl,'n'
jne convc0
test prflags[bp],F_LONGARG
jz gostorelen
mov ds,dx
gostorelen:
mov bx,ax
mov ax,procnt[bp]
mov [bx],ax
jmp disploop1
;
convc0:
lea di,convbuf[bp]
;
cmp bl,'c'
jne convc1
mov byte ptr ss:[di],al
inc di
mov bx,1
and prflags[bp],NOT (F_PREC OR F_PADZERO)
jmp out_conv
;
convc1:
cmp bl,'s'
jne convc2
test prflags[bp],F_LONGARG
jnz gofmtstring
mov dx,ds
gofmtstring:
and prflags[bp],NOT F_PADZERO
jmp fmtstring
;
convc2:
cmp bl,'b'
je fmtbin
cmp bl,'B'
je fmtbin
cmp bl,'x'
je fmthex
cmp bl,'X'
je fmthex
cmp bl,'p'
je fmtptr
cmp bl,'P'
je fmtptr
cmp bl,'u'
je fmtdec
cmp bl,'d'
jne badconv
test prflags[bp],F_LONGARG
jnz signedlong
test prflags[bp],F_SHORTARG
jz signedint
cbw
;
signedint:
test ah,80h
jz fmtdec
or prflags[bp],F_SIGNED
neg ax
jmp short fmtdec
;
signedlong:
test dh,80h
jz fmtdec
or prflags[bp],F_SIGNED
mov cx,dx
xor dx,dx
neg ax
sbb dx,cx
jmp short fmtdec
;
; Invalid conversion. Reset parameter pointer and output the
; char.
;
badconv:
pop di
pop es
mov al,bl
jmp dispchar
;
;
fmtdec:
call @decconv
test prflags[bp],F_SIGNED
jz fmtdnosign
mov byte ptr ss:[di],'-'
inc di
inc bx
fmtdnosign:
jmp short out_conv
;
fmtbin:
call @binconv
jmp short out_conv
;
fmthex:
mov prhexch[bp],'a'-10-'0'
cmp bl,'x'
je fmthex1
mov prhexch[bp],'A'-10-'0'
fmthex1:
call @hexconv
jmp short out_conv
;
fmtptr:
mov prhexch[bp],'a'-10-'0'
cmp bl,'p'
je fmtptr1
mov prhexch[bp],'A'-10-'0'
fmtptr1:
and prflags[bp],NOT (F_PREC OR F_PADZERO)
mov cl,4
mov bh,cl
xor bl,bl
;
fmtplo:
call @hexdigbp
shr ax,cl
dec bh
jnz fmtplo
test prflags[bp],F_LONGARG
jz out_conv
;
mov byte ptr ss:[di],':'
inc di
inc bl
mov bh,cl
mov ax,dx
;
fmtphilp:
call @hexdigbp
shr ax,cl
dec bh
jnz fmtphilp
;
;
out_conv:
mov cx,bx
call @padleft
add procnt[bp],cx
outc_out:
dec di
mov al,byte ptr ss:[di]
call prproc[bp]
loop outc_out
call @padright
jmp disploop1
;
;
fmtstring:
push si
push ds
mov ds,dx
mov si,ax
;
mov es,dx
mov di,ax
xor ax,ax
mov cx,-1
repne scasb
not cx
dec cx
test prflags[bp],F_PREC
jz fmtstr_np
cmp cx,prec[bp]
jbe fmtstr_np
mov cx,prec[bp]
;
fmtstr_np:
and prflags[bp],NOT F_PREC
mov bx,cx
call @padleft
jcxz fmtstr_end
add procnt[bp],cx
fmtstr_out:
lodsb
call prproc[bp]
loop fmtstr_out
fmtstr_end:
call @padright
pop ds
pop si
jmp disploop1
;
;
@disprintf endp
;
;
; void tsk_printf (char far *format, ...)
;
; Formatted output to console.
;
CGlobalfunc tsk_printf,<uses ds si di, fmt: far ptr, varg: word>
;
mov ax,ss
mov es,ax
lds si,fmt
lea di,varg
mov cx,offset @dischar
call @disprintf
ret
tsk_printf endp
;
;
; void tsk_vprintf (char far *format, void far *arg)
;
; Formatted output to console.
;
Globalfunc tsk_vprintf,<uses ds si di, fmt: far ptr, varg: far ptr>
;
lds si,fmt
les di,varg
mov cx,offset @dischar
call @disprintf
ret
tsk_vprintf endp
;
;
; void tsk_fprintf (int handle, char far *format, ...)
;
; Formatted output to file.
;
CGlobalfunc tsk_fprintf <uses ds si di, handle: word, fmt: far ptr, varg: word>
;
mov ax,ss
mov es,ax
lds si,fmt
lea di,varg
sub sp,FILE_BUFSIZE
mov dx,sp
mov bx,sp
mov byte ptr ss:[bx],0
mov cx,offset @filechar
mov bx,handle
call @disprintf
mov si,sp
mov cl,ss:[si]
xor ch,ch
jcxz fprintfend
mov dx,si
inc dx
mov bx,handle
mov ax,ss
mov ds,ax
mov ah,40h
int 21h
fprintfend:
add sp,FILE_BUFSIZE
ret
tsk_fprintf endp
;
;
; void tsk_vfprintf (int handle, char far *format, void far *arg)
;
; Formatted output to file.
;
Globalfunc tsk_vfprintf,<uses ds si di, handle: word, fmt: far ptr, varg: far ptr>
;
lds si,fmt
les di,varg
sub sp,FILE_BUFSIZE
mov dx,sp
mov bx,sp
mov byte ptr ss:[bx],0
mov cx,offset @filechar
mov bx,handle
call @disprintf
mov si,sp
mov cl,ss:[si]
xor ch,ch
jcxz vfprintfend
mov dx,si
inc dx
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -