printf (asm)

;-------------------------------------
; Version 1.1
; iuput: DS:SI text string (end with 0) followed with parameters
; control char:   use '%' first
;  %[-][,][nn][l|s]<b|o|d|h>
;   - ==> print neg number with use dec
;   , ==> use , spar per 3 numbers
;   nn ==> print width,bland left fill
;     if 0nn, 0 left fill
;   l/s ==> data as Dword/byte,ignore=word
;   b/o/d/h ==> format in bin/oct/dec/hex
;  %c  ==> data as String(end with 0)
;  %[nn]C  ==> data as string(end with 0)
;   nn ==> print nn bytes, fill right with blank
;  %<nn>r<Char> ==> fill nn numbers of Char
;  %<nn>t  ==> fill space to nn

STD_OUT  DW PRT_TO_SCR ;output Proc address
TABLE_COUNT DW ?
VAR_PTR  DW ?  ;start point of parameter
FILL_CHAR DB ' '  ;fill char in %xx format
SPAR_NUM DB 0  ;how many char/spar
PRT_FLAG DB ?
; bit0 ------ use spar
; bit1 ------ signal
; bit2 ------ quiet mode

HEX_TABLE DB '0123456789ABCDEF'

PRINTF  PROC

  pusha
  push var_ptr
  push word ptr prt_flag

  cld
  mov di,si
  xor al,al
  mov cx,-1
  repnz scasb
  mov var_ptr,di
  and prt_flag,11111100b ;clear spar and neg flag
prt_lop:
  lodsb
  or al,al
  jnz print_it

  pop word ptr prt_flag
  pop var_ptr
  popa
  ret
print_it:
  cmp al,'%'   ;is control char
  jz prt_ctrl  ;jump to prt_ctrl
prt_1:
  call std_out
  jmp short prt_lop
prt_ctrl:
  and prt_flag,11111101b ;clear spar and neg flag
prt_ctrl1:
  cmp byte ptr [si],'-' ;if neg
  jz ctrl_sub
  cmp byte ptr [si],',' ;if spar
  jnz signal
  or prt_flag,00000001b
  inc si
  jmp short prt_lop
ctrl_sub:
  or prt_flag,00000010b
  inc si
  jmp short prt_ctrl1
signal:  
  call get_num_len ;get format length in BP
  lodsb
  cmp al,'%'  ;print '%'
  jz prt_1
  cmp al,'c'  ;print string
  jz prt_string
  cmp al,'C'
  jz prt_string1
  cmp al,'r'  ;fill char
  jz prt_repc
  cmp al,'t'
  jz prt_table
  dec si  ;other return the char
  call get_num  ;get parameter
  call prt_space ;format width
  call prt_num  ;print out parameter
  jmp short prt_lop
prt_repc:
  lodsb   ;get fill char
  mov cx,bp
  or cx,cx
  jz prt_lop
prt_repc_lop:
  push ax
  call std_out
  pop ax
  loop prt_repc_lop
_prt_lop:
  jmp short prt_lop
prt_string1:
  push si
  mov si,var_ptr
  add var_ptr,2
  mov si,[si]
  or bp,bp
  jz prtstr_ret
  mov cx,bp
prtstr_lop:
  lodsb
  or al,al
  jz prtstr_lop1
  call std_out
  loop prtstr_lop
  jmp short prtstr_ret
prtstr_lop1:
  mov al,20h
  call std_out
  loop prtstr_lop1
prtstr_ret:
  pop si
  jmp short _prt_lop
prt_string:
  push si  ;print string
  mov si,var_ptr
  add var_ptr,2
  mov si,[si]
  call printf
  pop si
  jmp short _prt_lop
prt_table:
  cmp bp,table_count
  jbe _prt_lop
  mov al,20h
  call std_out
  jmp short prt_table

;-------------------------------
; get data format length
; return BP = format length

GET_NUM_LEN PROC

  lodsb
  mov cx,0a00h
  mov fill_char,' ' ;nn format ' ' left fill
  cmp al,'0'
  jnz gnl_lop
  mov fill_char,'0' ;0nn format then '0' left fill
gnl_lop:
  cmp al,'0'  ;not 0 to 9 end
  jb gnl_ret
  cmp al,'9'
  ja gnl_ret
  sub al,'0'
  push ax
  mov al,cl  ;final result may in CL
  mul ch
  mov cl,al
  pop ax
  add cl,al
  lodsb
  jmp short gnl_lop
gnl_ret:
  dec si  ;not 0 to 9 return this char
  xor ch,ch
  mov bp,cx  ;store result in BP
  ret

GET_NUM_LEN ENDP

;--------------------------------
; get data in DX:AX

GET_NUM  PROC

  lodsb
  mov cl,al
  cmp al,'l' ;long
  jz gn_ls
  cmp al,'s' ;short
  jnz gn_1
gn_ls:
  lodsb  ;if is 'l' or 's' get following char
gn_1:
  cmp al,'b' ;bin
  jz gn_bin
  cmp al,'o' ;oct
  jz gn_oct
  cmp al,'d' ;dec
  jz gn_dec
  cmp al,'h' ;hex
  jnz gn_dec
  mov di,16
  mov al,4
  jmp short gn_2
gn_bin:
  mov di,2
  mov al,8
  jmp short gn_2
gn_oct:
  mov di,8
  mov al,4
  jmp short gn_2
gn_dec:
  mov di,10
  mov al,3
gn_2:
  mov spar_num,al
  mov bx,var_ptr
  add var_ptr,2
  mov bx,[bx]  ;bx = parameter address
  xor dx,dx
  mov ax,[bx]  ;get parameter

  cmp cl,'s'
  jz gn_short
  cmp cl,'l'
  jz gn_long
  mov ax,[bx]
  test prt_flag,00000010b
  jz gn_ret
  cwd
  ret
gn_long:
  mov dx,[bx+2]
  ret
gn_short:
  xor ah,ah
  test prt_flag,00000010b
  jz gn_ret
  cbw
  cwd
gn_ret:
  ret

GET_NUM  ENDP

;-------------------------------------
; calculate and print in DI base
; input: DX:AX = data
;  DI = number base

PRT_NUM  PROC

  xor bp,bp  ;spar use
  cmp di,10  ;base 10 check +/- flag
  jnz prt_num1
  
  test prt_flag,00000010b ; +/-
  jz prt_num1
  test dx,8000h ;is -
  jz prt_num1
  not dx
  not ax
  add ax,1
  adc dx,0
  
  push ax
  mov al,'-'
  call std_out
  pop ax
prt_num1:
  inc bp  ;BP = data width
  push ax
  mov ax,dx
  xor dx,dx
  div di
  mov bx,ax
  pop ax
  div di
  xchg bx,dx
  push ax
  or ax,dx
  pop ax
  jz prt_inc_1
  push bx
  call prt_num1
  pop bx
prt_inc_1:
  mov al,hex_table [bx]
  call std_out

  test prt_flag,00000001b ;use ,
  jz prt_inc_2
  
  dec bp
  mov ax,bp
  div spar_num
  
  or al,al
  jz prt_inc_2
  or ah,ah
  jnz prt_inc_2
  mov al,','
  call std_out
prt_inc_2:
  ret

PRT_NUM  ENDP

;---------------------------------------
; input: BP = data format length
;  DX:AX = data

PRT_SPACE PROC

  pusha
  push std_out
  mov std_out,offset prt_count
  xor cx,cx

  push bp
  call prt_num  ;count has how many chars
  pop bp  ;return CX = chars

  pop std_out
  push bp
  xchg cx,bp
  sub cx,bp
  pop bp

  cmp cx,0
  jle prt_space1
prt_space_lop:
  mov ax,bp
  mov bl,spar_num
  inc bl
  dec bp
  div bl
  mov al,fill_char

  test prt_flag,00000001b
  jz ps_prt
  or ah,ah
  jnz ps_prt
  cmp al,' '
  jz ps_prt
  mov al,','
ps_prt:
  call std_out
  loop prt_space_lop
prt_space1:
  popa
  ret

PRT_SPACE ENDP

;--------------------------------
; count for %xx format

PRT_COUNT PROC

  inc cx
  ret

PRT_COUNT ENDP

;-------------------------------------
; print to screen proc
; don't change resigter except AX
PRT_TO_SCR PROC

  cmp al,0dh
  jnz pts_1
  mov table_count,0
  jmp short pts_3
pts_1:
  cmp al,08h
  jnz pts_2
  dec table_count
  jmp short pts_3
pts_2:
  inc table_count
pts_3:
  test prt_flag,00000100b
  jnz pts_ret
  mov ah,0eh
  mov bl,7
  int 10h
pts_ret:
  ret

PRT_TO_SCR ENDP

PRINTF  ENDP

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值