-
Notifications
You must be signed in to change notification settings - Fork 0
/
printf.inc
208 lines (187 loc) · 2.62 KB
/
printf.inc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
;--- simple printf() implementation
handle_char proc
mov dl,al
cmp al,10
jnz @F
mov dl,13
call @F
mov dl,10
@@:
mov ah,2
int 21h
ret
handle_char endp
;--- ltob(long n, char * s, int base);
;--- convert long to string
ltob PROC stdcall uses edi number:dword, outb:word, base:word
mov ch,0
movzx edi, base
mov eax, number
cmp di,-10
jne @F
mov di,10
and eax,eax
jns @F
neg eax
mov ch,'-'
@@:
mov bx,outb
add bx,10
mov BYTE PTR [bx],0
dec bx
@@nextdigit:
xor edx, edx
div edi
add dl,'0'
cmp dl,'9'
jbe @F
add dl,7+20h
@@:
mov [bx],dl
dec bx
and eax, eax
jne @@nextdigit
cmp ch,0
je @F
mov [bx],ch
dec bx
@@:
inc bx
mov ax,bx
ret
ltob ENDP
printf PROC c uses es si di bx fmt:ptr byte, args:VARARG
local size_:word
local flag:byte
local longarg:byte
local fill:byte
local szTmp[12]:byte
lea di,[fmt+2]
@@L335:
mov si,[fmt]
nextchar:
lodsb
or al,al
je done
cmp al,'%'
je formatitem
call handle_char
jmp nextchar
done:
xor ax,ax
ret
formatitem:
push @@L335
xor dx,dx
mov [longarg],dl
mov bl,1
mov cl,' '
cmp BYTE PTR [si],'-'
jne @F
dec bx
inc si
@@:
mov [flag],bl
cmp BYTE PTR [si],'0'
jne @F
mov cl,'0'
inc si
@@:
mov [fill],cl
mov bx,dx
.while BYTE PTR [si] >= '0' && BYTE PTR [si] <= '9'
lodsb
sub al,'0'
cbw
imul cx,bx,10 ;cx = bx * 10
add ax,cx
mov bx,ax
.endw
mov [size_],bx
cmp BYTE PTR [si],'l'
jne @F
mov [longarg],1
inc si
@@:
lodsb
mov [fmt],si
cmp al,'x'
je handle_x
cmp al,'X'
je handle_x
cmp al,'c'
je handle_c
cmp al,'d'
je handle_d
cmp al,'i'
je handle_i
cmp al,'s'
je handle_s
cmp al,'u'
je handle_u
and al,al
jnz @@L359
pop ax
jmp done
handle_c:
mov ax,[di]
add di,2
@@L359:
call handle_char
retn
handle_s:
mov si,[di]
add di,2
jmp @@do_outputstring
handle_x:
mov bx,16
jmp @@lprt262
handle_d:
handle_i:
mov bx,-10
jmp @@lprt262
handle_u:
mov bx,10
@@lprt262:
mov ax,[di]
add di,2
sub dx,dx
cmp bx,0 ;signed or unsigned?
jge @F
cwd
@@:
cmp [longarg],0
je @F
mov dx,[di]
add di,2
@@:
lea cx,[szTmp]
invoke ltob, dx::ax, cx, bx
mov si,ax
@@do_outputstring:
mov ax,si
mov bx,size_
.while byte ptr [si]
inc si
.endw
sub si,ax
xchg ax,si
sub bx,ax
.if flag == 1
.while sword ptr bx > 0
mov al,[fill]
call handle_char
dec bx
.endw
.endif
.while byte ptr [si]
lodsb
call handle_char
.endw
.while sword ptr bx > 0
mov al,[fill]
call handle_char
dec bx
.endw
retn
printf ENDP