?? 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 + -