MS-DOS TASMMASM 函式讀取一個 16 位無符號整數
從輸入讀取一個 16 位無符號整數
此函式使用中斷服務 Int 21 / AH = 0Ah 來讀取緩衝的字串。
使用緩衝字串可以讓使用者在將其傳遞給程式進行處理之前檢視他們輸入的內容。
最多讀取六位數(因為 65535 = 2 16 - 1 有六位數)。
除了執行從數字到數字的標準轉換之外,此功能還檢測無效輸入和溢位(數字太大而不適合 16 位)。
返回值
該函式返回 AX
中讀取的數字。標誌 ZF
,CF
,OF
判斷操作是否成功完成以及原因。
錯誤 | 斧頭 | ZF | CF | |
---|---|---|---|---|
None |
16 位整數 | 組 | 沒有設定 | 沒有設定 |
Invalid input |
部分轉換的數字,直到遇到的最後一個有效數字 | 沒有設定 | 組 | 沒有設定 |
Overflow |
7FFFH | 沒有設定 | 組 | 組 |
ZF
可用於快速分辨有效與無效輸入。
用法
call read_uint16
jo _handle_overflow ;Number too big (Optional, the test below will do)
jnz _handle_invalid ;Number format is invalid
;Here AX is the number read
碼
;Returns:
;
;If the number is correctly converted:
; ZF = 1, CF = 0, OF = 0
; AX = number
;
;If the user input an invalid digit:
; ZF = 0, CF = 1, OF = 0
; AX = Partially converted number
;
;If the user input a number too big
; ZF = 0, CF = 1, OF = 1
; AX = 07fffh
;
;ZF/CF can be used to discriminate valid vs invalid inputs
;OF can be used to discrimate the invalid inputs (overflow vs invalid digit)
;
read_uint16:
push bp
mov bp, sp
;This code is an example in Stack Overflow Documentation project.
;x86/Converting Decimal strings to integers
;Create the buffer structure on the stack
sub sp, 06h ;Reserve 6 byte on the stack (5 + CR)
push 0006h ;Header
push ds
push bx
push cx
push dx
;Set DS = SS
mov ax, ss
mov ds, ax
;Call Int 21/AH=0A
lea dx, [bp-08h] ;Address of the buffer structure
mov ah, 0ah
int 21h
;Start converting
lea si, [bp-06h]
xor ax, ax
mov bx, 10
xor cx, cx
_r_ui16_convert:
;Get current char
mov cl, BYTE PTR [si]
inc si
;Check if end of string
cmp cl, CR_CHAR
je _r_ui16_end ;ZF = 1, CF = 0, OF = 0
;Convert char into digit and check
sub cl, '0'
jb _r_ui16_carry_end ;ZF = 0, CF = 1, OF = X -> 0
cmp cl, 9
ja _r_ui16_carry_end ;ZF = 0, CF = 0 -> 1, OF = X -> 0
;Update the partial result (taking care of overflow)
;AX = AX * 10
mul bx
;DX:AX = DX:AX + CX
add ax, cx
adc dx, 0
test dx, dx
jz _r_ui16_convert ;No overflow
;set OF and CF
mov ax, 8000h
dec ax
stc
jmp _r_ui16_end ;ZF = 0, CF = 1, OF = 1
_r_ui16_carry_end:
or bl, 1 ;Clear OF and ZF
stc ;Set carry
;ZF = 0, CF = 1, OF = 0
_r_ui16_end:
;Don't mess with flags hereafter!
pop dx
pop cx
pop bx
pop ds
mov sp, bp
pop bp
ret
CR_CHAR EQU 0dh
NASM 移植
要將程式碼移植到 NASM,請從記憶體訪問中刪除 PTR
關鍵字(例如,mov cl, BYTE PTR [si]
變為 mov cl, BYTE [si]
)