📄 stdio386.inc
字号:
;=============================stdio386.inc==============================
;Created by RunningOn Chen.
;2003011434 J34 CS dept, THU
;2005-12-15
;Procedures and macros for standard input/output for .386 mode
;
;Procedures:
;output_dec : output EAX in decimal. signed.
;input_dec : input a decimal to EAX. signed. If errors, C=1
;std_getchar: get a char to al
;
;Macros:
;DOS21 : call int 21 in a more convenience way.
; parameters : DOSFUNC [BUFF]
; DOSFUNC : function number
; BUFF : if exists, proceed "mov edx, offset BUFF"
;std_input : input a string
; parameters : buffer to input
;std_otuput: output a string
; parameters : buffer to output
;std_putchar: output a char
; parameters : char to output
;Copyright(C) RunningOn Chen, Department of CS/T, Tsinghua University.
;=======================================================================
.data
input_dec_buffer db 9, ?, 7 dup(?)
stdio386_newline db 0dh, 0ah, '$'
.code
;============================== macros ===============================
DOS21 macro DOSFUNC, BUFF ;;21h号中断调用。
IFNB <BUFF> ;;如果BUFF不为空
mov edx, offset BUFF
ENDIF
mov ah, DOSFUNC
int 21h
endm
output_dec_FIGURE macro MASK ;; 输出eax/MASK的商,余数存入eax。这是output_dec的辅助宏
local output_dec_FIGURE_OUTPUT, output_dec_FIGURE_EXIT
push edx ;; ecx为0表示之前没有输出任何数。否则输出过
push ebx
mov ebx, MASK
mov edx, 0
div ebx
mov ebx, edx ;;把余数备份到ebx
mov dl, al
test al, al
jnz output_dec_FIGURE_OUTPUT
test ecx, ecx ;;为0,判断一下要不要输出
jz output_dec_FIGURE_EXIT
output_dec_FIGURE_OUTPUT:
add dl, '0'
DOS21 02 ;;输出
mov ecx, 1
output_dec_FIGURE_EXIT:
mov eax, ebx ;;把余数放入eax
pop ebx
pop edx
endm
std_input macro buffer ;; 输入一字符串到buffer.
push eax
push edx
DOS21 0ah, buffer ;; 获取输入
DOS21 09h, stdio386_newline ;; 输入一个回车
pop edx
pop eax
endm
std_output macro buffer ;; 输出一字符串buffer.
push eax
push edx
DOS21 09h, buffer
pop edx
pop eax
endm
std_putchar macro char ;; 输出一个字符char
push edx
push eax
mov al, 02h
mov dl, char
int 21h
pop eax
pop edx
endm
;==============================output_dec proc===================================
;以十进制输出。输入:eax为待输出的数,有正负之分。
output_dec proc near
push eax
push ebx
push ecx
push edx
test eax, eax ; 看看是不是负数
jns output_dec_start
push eax
mov dl, '-'
DOS21 02 ; 输出一个负号
pop eax
neg eax
output_dec_start:
mov ecx, 0 ; 输出之前要把ecx清0
test eax, eax ; 如果是0,直接输出
jnz output_dec_nonzero
mov dl, '0'
DOS21 02
jmp output_dec_exit
output_dec_nonzero:
output_dec_FIGURE 1000000000 ;一位一位地输出。但不会输出前导的零。
output_dec_FIGURE 100000000
output_dec_FIGURE 10000000
output_dec_FIGURE 1000000
output_dec_FIGURE 100000
output_dec_FIGURE 10000
output_dec_FIGURE 1000
output_dec_FIGURE 100
output_dec_FIGURE 10
output_dec_FIGURE 1
output_dec_exit:
pop edx
pop ecx
pop ebx
pop eax
ret
output_dec endp
;==============================input_dec proc===================================
input_dec proc near ;;输入十进制数到eax,有正负之分。若不正确,将C置1
push ebx
push ecx
push edx
push esi
DOS21 0ah, input_dec_buffer ; 先输入一字符串
mov edx, offset input_dec_buffer+2
mov eax, 0
mov al, input_dec_buffer[1]
;输入:ds:edx存缓冲区地址,eax为缓冲区长
;输出:eax为转换后的结果。如果不正确,将C置1
mov esi, edx ; 用si取代dx
mov ebx, 0
mov bl, [esi]
cmp bl, '-'
jne input_dec_plus
mov bh, 1 ; bh=1表示负数
inc esi
dec eax
jmp input_dec_check_valid
input_dec_plus:
cmp bl, '+'
jne input_dec_check_valid
inc esi
dec eax ; 表示指针加1, 有效的缓冲区长度减一
input_dec_check_valid: ; 检查输入是否有非法字符
push esi ; 保存si ax bx
push eax
push ebx
mov ecx, eax
mov ebx, eax
input_dec_check_valid_cycle:
dec ebx
mov edx, 0
mov dl, [esi][ebx]
cmp dl, '0'
jb input_dec_invalid
cmp dl, '9'
ja input_dec_invalid
loop input_dec_check_valid_cycle
jmp input_dec_transfer
input_dec_invalid:
pop ebx
pop eax
pop esi
std_output stdio386_newline ;输出一回车
pop esi
pop edx
pop ecx
pop ebx
stc ; 表示有错误
ret
input_dec_transfer: ; 开始转换到二进制
pop ebx
pop eax
pop esi ; 恢复si ax bx. si为指针, ax为长度
push ebx ; bh中保存着正负的信息
mov ecx, eax
mov eax, 0
mov ebx, 0
input_dec_transfer_next:
mov edx, 10
mul edx ; 不考虑溢出,认为edx=0
mov edx, 0
mov dl, [esi][ebx]
add eax, edx
sub eax, 30h
inc ebx
loop input_dec_transfer_next
pop ebx
test bh, bh ; 0为正,1为负
jz input_dec_exit
neg eax
input_dec_exit:
push eax
std_output stdio386_newline ;输出一回车
pop eax
pop esi
pop edx
pop ecx
pop ebx
clc ; 表示正常退出
ret
input_dec endp
;==============================std_getchar proc===================================
std_getchar proc near ;; 得到一个输入,存到al
mov al, 01h
int 21h
std_getchar endp
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -