📄 prf.asm
字号:
;/++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; printn subroutine will include putchar implementation, so there's
; no separate putchar subroutine, the parameters pass to printf
; subroutine is unpredicable but the first variable always can be
; found use [bp+10] to call printf, a string table must be linked
; in the 'global' data segment each entries in string table should
; be terminated with '$' sign, other wise it will constipate the
; whole system completely
;
; The entry points into this file are
; printn: printf the unsigned 16bit integer
; printf: scale down version of the printf in standard C library
; dispstr: BIOS call verion of string display
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++/
include comstruc.inc
sseg segment stack
db 128 dup (0)
sseg ends
dseg segment para public 'global'
;debug printf
extrn fmt1:byte
extrn fmt2:byte
extrn fmt3:byte
extrn fmt4:byte
extrn debugstr:byte
extrn number:word
dseg ends
cseg segment para public 'code'
assume cs:cseg,ds:dseg,es:dseg,ss:sseg
public printn,printf,dispstr
;/============================================================================
;
; printn
;
;============================================================================/
printn proc near
push ds
push es
push bp
mov bp,sp
mov bx,10[bp] ; get base number
mov ax,8[bp] ; assume 16bit unsigned integer
xor dx,dx
div bx ; assume no overflow (dx < 65535)
push dx ; must be saved
cmp ax,0
je nnext1 ; if(a = ldiv(n,b))
push bx ; pass base #
push ax ; pass integer value
call printn ; recursive call
pop cx
pop cx ; obsolete the paramters
nnext1:
pop dx ; restore local variable
add dx,30h ; + '0'
xor dh,dh
;dx only lower 8bit significated at this moment
push dx
call dispchar
pop cx
mov sp,bp
pop bp
pop es
pop ds
ret
printn endp
;/============================================================================
;
; printf
;
;============================================================================/
; prototype printf(char fmt[],int x1,int x2,int x3 ...)
printf proc near
push ds
push es
push bp
mov bp,sp
sub sp,4 ; alloc for c, adx
mov ax,bp
add ax,10
mov [bp-4],ax ; adx = &x1
; remember to use ss prefix this is a stack address
ploop: ; // while
mov si,8[bp]
mov bx,[si] ; double indirect operand fetch
mov [bp-2],bl ; fetch the character in 'global' storage
; be careful only bl contain the ASCII code, mov [bp-2],bx is wrong!
inc word ptr 8[bp] ; c = *fmt ++
cmp byte ptr [bp-2],25h ; '%'
je pnext1
cmp byte ptr [bp-2],36 ; '$', string end should with '$' for DOS call
jne pnext2
mov sp,bp
pop bp
pop es
pop ds
ret ; subroutine end here
pnext2:
mov dx,[bp-2]
push dx
call dispchar
pop cx
jmp ploop ; // while end
pnext1:
mov si,8[bp]
mov bx,[si]
mov [bp-2],bx
inc word ptr 8[bp] ; skip '%' character
cmp bl,64h ; 'd'
je pnext3 ; process decimal
cmp bl,6ch ; 'l'
je pnext3 ; process decimal
cmp bl,6fh ; 'o'
je pnext4 ; process octal
jmp pnext5 ; nothing to do
pnext4:
mov ax,8
jmp pnext6
pnext3:
mov ax,10
pnext6:
push ax
mov si,[bp-4]
mov bx,ss:[si] ; need ss prefix, this is a stack address
push bx
call printn
pop cx
pop cx ; obsolete stack
pnext5:
cmp byte ptr [bp-2],73h ; if (c == 's')
jne pnext7
; the string address is not [bp-4] any more
; DOS 9# system call requires dx as index
; so just fetch the index from stack
mov si,[bp-4]
; before we use DOS 9# system call
; we must first assume stack segment
; as data segment
; stack address require ss prefix
mov dx,ss:[si] ; load string address
push dx
call dispstr
pop cx
pnext7:
inc si
inc si ; adx stepping as integer
mov [bp-4],si
jmp ploop
printf endp
;/============================================================================
;
; dispstr
;
;============================================================================/
dispstr proc near
push ds
push es
push si
push di
push bp
mov bp,sp
sub sp,2
; stack arranges like this
;
; [bp-2] : display address
mov ax,12[bp]
mov [bp-2],ax
mov si,[bp-2]
disp:
lodsb
cmp al,36 ; '$'
jz dispover
push si
mov bx,7
mov ah,0eh
int 10h
pop si
jmp disp
dispover:
mov sp,bp
pop bp
pop di
pop si
pop es
pop ds
ret
dispstr endp
;/============================================================================
;
; dispchar
;
;============================================================================/
dispchar proc near
push ds
push es
push si
push di
push bp
mov bp,sp
sub sp,2
; stack arranges like this
;
; [bp-2] : display address
mov ax,12[bp]
mov [bp-2],ax
mov al,[bp-2]
mov bx,7
mov ah,0eh
int 10h
mov sp,bp
pop bp
pop di
pop si
pop es
pop ds
ret
dispchar endp
cseg ends
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -