📄 io.asm
字号:
ok: imul WORD PTR [ebp-2] ; make signed number
ok1: popf ; get original flags
test ax,ax ; set flags for new number
pushf ; save flags
AToIExit: popf ; get flags
pop edx ; restore registers
pop ecx
pop ebx
mov esp, ebp ; delete local variable space
pop ebp
ret 4 ; exit, removing parameter
atoiproc ENDP
; atodproc(source)
; Procedure to scan data segment starting at source address, interpreting
; ASCII characters as an integer value which is returned in EAX.
; Leading blanks are skipped. A leading - or + sign is acceptable.
; Digit(s) must immediately follow the sign (if any).
; Memory scan is terminated by any non-digit, and the address of
; the terminating character is in ESI.
; The following flags are affected:
; AC is undefined
; PF, SF and ZF reflect sign of number returned in EAX.
; CF reset to 0
; OF set to indicate error. Possible error conditions are:
; - no digits in input
; - value outside range -2,147,483,648 to 2,147,483,647
; (EAX) will be 0 if OF is set.
atodproc PROC NEAR32
push ebp ; save base pointer
mov ebp, esp ; establish stack frame
sub esp, 4 ; local space for sign
push ebx ; Save registers
push ecx
push edx
pushf ; save flags
mov esi,[ebp+8] ; get parameter (source addr)
WhileBlankD:cmp BYTE PTR [esi],' ' ; space?
jne EndWhileBlankD ; exit if not
inc esi ; increment character pointer
jmp WhileBlankD ; and try again
EndWhileBlankD:
mov eax,1 ; default sign multiplier
IfPlusD: cmp BYTE PTR [esi],'+' ; leading + ?
je SkipSignD ; if so, skip over
IfMinusD: cmp BYTE PTR [esi],'-' ; leading - ?
jne EndIfSignD ; if not, save default +
mov eax,-1 ; -1 for minus sign
SkipSignD: inc esi ; move past sign
EndIfSignD:
mov [ebp-4],eax ; save sign multiplier
mov eax,0 ; number being accumulated
mov cx,0 ; count of digits so far
WhileDigitD:cmp BYTE PTR [esi],'0' ; compare next character to '0'
jl EndWhileDigitD ; not a digit if smaller than '0'
cmp BYTE PTR [esi],'9' ; compare to '9'
jg EndWhileDigitD ; not a digit if bigger than '9'
imul eax,10 ; multiply old number by 10
jo overflowD ; exit if product too large
mov bl,[esi] ; ASCII character to BL
and ebx,0000000Fh ; convert to single-digit integer
add eax,ebx ; add to sum
jc overflowD ; exit if sum too large
inc cx ; increment digit count
inc esi ; increment character pointer
jmp WhileDigitD ; go try next character
EndWhileDigitD:
cmp cx,0 ; no digits?
jz overflowD ; if so, set overflow error flag
; if value is 80000000h and sign is '-', want to return 80000000h (-2^32)
cmp eax,80000000h ; 80000000h ?
jne TooBigD?
cmp DWORD PTR [ebp-4],-1 ; multiplier -1 ?
je ok1D ; if so, return 8000h
TooBigD?: test eax,eax ; check sign flag
jns okD ; will be set if number > 2^32 - 1
overflowD: pop ax ; get flags
or ax,0000100001000100B ; set overflow, zero & parity flags
and ax,1111111101111110B ; reset sign and carry flags
push ax ; push new flag values
mov eax,0 ; return value of zero
jmp AToDExit ; quit
okD: imul DWORD PTR [ebp-4] ; make signed number
ok1D: popf ; get original flags
test eax,eax ; set flags for new number
pushf ; save flags
AToDExit: popf ; get flags
pop edx ; restore registers
pop ecx
pop ebx
mov esp, ebp ; delete local variable space
pop ebp
ret 4 ; exit, removing parameter
atodproc ENDP
; *************** setup for Win32 I/O ****************
STD_OUTPUT EQU -11
STD_INPUT EQU -10
GetStdHandle PROTO NEAR32 stdcall,
nStdHandle:DWORD
ReadFile PROTO NEAR32 stdcall,
hFile:DWORD, lpBuffer:NEAR32, nNumberOfCharsToRead:DWORD,
lpNumberOfBytesRead:NEAR32, lpOverlapped:NEAR32
WriteFile PROTO NEAR32 stdcall,
hFile:DWORD, lpBuffer:NEAR32, nNumberOfCharsToWrite:DWORD,
lpNumberOfBytesWritten:NEAR32, lpOverlapped:NEAR32
.DATA
written DWORD ?
read DWORD ?
strAddr DWORD ?
strLength DWORD ?
hStdOut DWORD ?
hStdIn DWORD ?
.CODE
; outproc(source)
; Procedure to display null-terminated string
; No registers are changed; flags are not affected.
outproc PROC NEAR32
push ebp ; save base pointer
mov ebp, esp ; establish stack frame
pushad
pushfd ; save flags
mov esi,[ebp+8] ; source address
mov strAddr, esi
; find string length
mov strLength, 0 ; initialize string length
WhileChar: cmp BYTE PTR [esi], 0 ; character = null?
jz EndWhileChar ; exit if so
inc strLength ; increment character count
inc esi ; point at next character
jmp WhileChar
EndWhileChar:
INVOKE GetStdHandle, ; get handle for console output
STD_OUTPUT
mov hStdOut, eax
INVOKE WriteFile,
hStdOut, ; file handle for screen
strAddr, ; address of string
strLength, ; length of string
NEAR32 PTR written, ; bytes written
0 ; overlapped mode
popfd ; restore flags
popad ; restore registers
pop ebp
ret 4 ;exit, discarding parameter
outproc ENDP
; inproc(dest,length)
; Procedure to input a string from keyboard.
; The string will be stored at the address given by dest.
; The length parameter gives the size of the user's buffer. It is assumed
; that there will be room for the string and a null byte.
; The string will be terminated by a null character (00h).
; Flags are unchanged.
inproc PROC NEAR32
push ebp ; save base pointer
mov ebp, esp ; establish stack frame
pushad ; save all registers
pushfd ; save flags
INVOKE GetStdHandle, ; get handle for console
STD_INPUT
mov hStdIn, eax
mov ecx, [ebp+8] ; string length
mov strLength, ecx
mov esi, [ebp+12] ; source address
mov strAddr, esi
INVOKE ReadFile,
hStdIn, ; file handle for keyboard
strAddr, ; address of string
strLength, ; length of string
NEAR32 PTR read, ; bytes read
0 ; overlapped mode
mov ecx, read ; number of bytes read
mov BYTE PTR [esi+ecx-2],0 ; replace CR/LF by trailing null
popfd ; restore flags
popad ; restore registers
pop ebp
ret 8 ; exit, discarding parameters
inproc ENDP
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -