📄 irvine32.asm
字号:
;--------------------------------------------------
Gotoxy proc
;
; Locate the cursor
; Receives: DH = screen row, DL = screen column
; Last update: 7/11/01
;--------------------------------------------------------
.data
_cursorPosition COORD <>
.code
pushad
CheckInit
movzx ax,dl
mov _cursorPosition.X, ax
movzx ax,dh
mov _cursorPosition.Y, ax
INVOKE SetConsoleCursorPosition, consoleOutHandle, _cursorPosition
popad
ret
Gotoxy endp
;-----------------------------------------------
Isdigit PROC
;
; Determines whether the character in AL is a
; valid decimal digit.
; Receives: AL = character
; Returns: ZF=1 if AL contains a valid decimal
; digit; otherwise, ZF=0.
;-----------------------------------------------
cmp al,'0'
jb ID1
cmp al,'9'
ja ID1
test ax,0 ; set ZF = 1
ID1: ret
Isdigit ENDP
;--------------------------------------------------------------
RandomRange proc
;
; Returns an unsigned pseudo-random 32-bit integer
; in EAX, between 0 and n-1. Input parameter:
; EAX = n.
; Last update: 7/11/01
;--------------------------------------------------------------
push bp
mov bp,sp
push ebx
push edx
mov ebx,eax ; maximum value
call Random32 ; eax = random number
mov edx,0
div ebx ; divide by max value
mov eax,edx ; return the remainder
pop edx
pop ebx
pop bp
ret
RandomRange endp
;--------------------------------------------------------------
Random32 proc
;
; Returns an unsigned pseudo-random 32-bit integer
; in EAX,in the range 0 - FFFFFFFFh.
; Last update: 7/11/01
;--------------------------------------------------------------
.data
seed dd 1
.code
push edx
mov eax, 343FDh
imul seed
add eax, 269EC3h
mov seed, eax ; save the seed for the next call
ror eax,8 ; rotate out the lowest digit (10/22/00)
pop edx
ret
Random32 endp
;--------------------------------------------------------
Randomize proc
;
; Re-seeds the random number generator with the current time
; in seconds.
; Receives: nothing
; Returns: nothing
; Last update: 7/11/01
;--------------------------------------------------------
push eax
INVOKE GetSystemTime,offset sysTime
movzx eax,sysTime.wMilliseconds
mov seed,eax
pop eax
ret
Randomize endp
;---------------------------------------------------------
ReadChar proc
;
; Reads one character from standard input and echoes
; on the screen. Waits for the character if none is
; currently in the input buffer.
; Receives: nothing
; Returns: AL = ASCII code
; Last update: 9/24/01
;----------------------------------------------------------
.data
saveFlags DWORD ?
.code
pushad
CheckInit
; Get & save the current console input mode flags:
invoke GetConsoleMode,consoleInHandle,offset saveFlags
; Clear all flags
invoke SetConsoleMode,consoleInHandle,0
; Read a single character from input buffer:
INVOKE ReadConsole,
consoleInHandle, ; console input handle
ADDR buffer, ; pointer to buffer
1, ; max characters to read
ADDR bytesRead,0
; Restore the previous flags state:
invoke SetConsoleMode,consoleInHandle,saveFlags
popad
mov al,buffer ; return the input character
ret
ReadChar endp
;--------------------------------------------------------
ReadHex PROC
;
; Reads a 32-bit hexadecimal integer from standard input,
; stopping when the Enter key is pressed.
; Receives: nothing
; Returns: EAX = binary integer value
; Remarks: No error checking performed for bad digits
; or excess digits.
; Last update: 11/7/01
;--------------------------------------------------------
.data
HMAX_DIGITS = 128
Hinputarea BYTE HMAX_DIGITS dup(0),0
xbtable BYTE 0,1,2,3,4,5,6,7,8,9,7 DUP(0FFh),10,11,12,13,14,15
numVal DWORD ?
charVal BYTE ?
.code
push ebx
push ecx
push edx
push esi
mov edx,OFFSET Hinputarea
mov esi,edx ; save in ESI also
mov ecx,HMAX_DIGITS
call ReadString ; input the string
mov ecx,eax ; save length in ECX
; Start to convert the number.
B4: mov numVal,0 ; clear accumulator
mov ebx,OFFSET xbtable ; translate table
; Repeat loop for each digit.
B5: mov al,[esi] ; get character from buffer
cmp al,'F' ; lowercase letter?
jbe B6 ; no
and al,11011111b ; yes: convert to uppercase
B6:
sub al,30h ; adjust for table
xlat ; translate to binary
mov charVal,al
mov eax,16 ; numVal *= 16
mul numVal
mov numVal,eax
movzx eax,charVal ; numVal += charVal
add numVal,eax
inc esi ; point to next digit
loop B5 ; repeat, decrement counter
mov eax,numVal ; return binary result
pop esi
pop edx
pop ecx
pop ebx
ret
ReadHex ENDP
;--------------------------------------------------------
ReadInt PROC uses ebx ecx edx esi
LOCAL Lsign:DWORD, saveDigit:DWORD
;
; Reads a 32-bit signed decimal integer from standard
; input, stopping when the Enter key is pressed.
; All valid digits occurring before a non-numeric character
; are converted to the integer value. Leading spaces are
; ignored, and an optional leading + or - sign is permitted.
; Receives: nothing
; Returns: If CF=0, the integer is valid, and EAX = binary value.
; If CF=1, the integer is invalid and EAX = 0.
;
; Credits: Thanks to Courtney Amor, a student at the UCLA Mathematics
; department, for pointing out improvements that have been
; implemented in this version.
; Last update: 1/27/02
;--------------------------------------------------------
.data
LMAX_DIGITS = 80
Linputarea BYTE LMAX_DIGITS dup(0),0
overflow_msgL BYTE " <32-bit integer overflow>",0
invalid_msgL BYTE " <invalid integer>",0
.code
; Input a string of digits using ReadString.
mov edx,offset Linputarea
mov esi,edx ; save offset in SI
mov ecx,LMAX_DIGITS
call ReadString
mov ecx,eax ; save length in CX
mov Lsign,1 ; assume number is positive
cmp ecx,0 ; greater than zero?
jne L1 ; yes: continue
mov eax,0 ; no: set return value
jmp L10 ; and exit
; Skip over any leading spaces.
L1: mov al,[esi] ; get a character from buffer
cmp al,' ' ; space character found?
jne L2 ; no: check for a sign
inc esi ; yes: point to next char
loop L1
jcxz L8 ; quit if all spaces
; Check for a leading sign.
L2: cmp al,'-' ; minus sign found?
jne L3 ; no: look for plus sign
mov Lsign,-1 ; yes: sign is negative
dec ecx ; subtract from counter
inc esi ; point to next char
jmp L4
L3: cmp al,'+' ; plus sign found?
jne L4 ; no: must be a digit
inc esi ; yes: skip over the sign
dec ecx ; subtract from counter
; Test the first digit, and exit if it is nonnumeric.
L3A:mov al,[esi] ; get first character
call IsDigit ; is it a digit?
jnz L7A ; no: show error message
; Start to convert the number.
L4: mov eax,0 ; clear accumulator
mov ebx,10 ; EBX is the divisor
; Repeat loop for each digit.
L5: mov dl,[esi] ; get character from buffer
cmp dl,'0' ; character < '0'?
jb L9
cmp dl,'9' ; character > '9'?
ja L9
and edx,0Fh ; no: convert to binary
mov saveDigit,edx
imul ebx ; EDX:EAX = EAX * EBX
mov edx,saveDigit
jo L6 ; quit if overflow
add eax,edx ; add new digit to AX
jo L6 ; quit if overflow
inc esi ; point to next digit
jmp L5 ; get next digit
; Overflow has occured, unlesss EAX = 80000000h
; and the sign is negative:
L6: cmp eax,80000000h
jne L7
cmp Lsign,-1
jne L7 ; overflow occurred
jmp L9 ; the integer is valid
; Choose "integer overflow" messsage.
L7: mov edx,OFFSET overflow_msgL
jmp L8
; Choose "invalid integer" message.
L7A:
mov edx,OFFSET invalid_msgL
; Display the error message pointed to by EDX.
L8: call WriteString
call Crlf
stc ; set Carry flag
mov eax,0 ; set return value to zero
jmp L10 ; and exit
L9: imul Lsign ; EAX = EAX * sign
L10:ret
ReadInt ENDP
;--------------------------------------------------------
ReadString proc
;
; Reads a string of up to 128 characters from the console
; past the end of line, and places the characters in a buffer.
; Strips off CR/LF from the input buffer.
; Receives: EDX points to the input buffer,
; ECX contains the maximum string length
; Returns: EAX = size of the input string.
; Comments: Stops when Enter key (0Dh) is pressed. Because ReadConsole
; places 0Dh,0Ah in the buffer, we have to use a local variable
; to overwriting the caller's memory. After calling ReadConsole,
; we copy the characters back to the caller's buffer.
; Last update: 8/14/01
;--------------------------------------------------------
.data
READSTRING_BUFSIZE = 128
InputTooLong BYTE "ReadString error: Cannot input string longer than 128 bytes.",0Dh,0Ah,0
localBuf BYTE (READSTRING_BUFSIZE + 2) DUP(?)
.code
pushad
CheckInit
cmp ecx,READSTRING_BUFSIZE
ja L3Err ; InputTooLong
add ecx,2 ; include CR/LF in the input
push edx
INVOKE ReadConsole,
consoleInHandle, ; console input handle
OFFSET localBuf, ; pointer to local buffer
ecx, ; max count
OFFSET bytesRead,
0
pop edx
sub bytesRead,2 ; adjust character count
jz L5 ; skip move if zero chars input
L1:
; Copy from the local buffer to the caller's buffer.
mov ecx,bytesRead
mov esi,OFFSET localBuf
L2:
mov al,[esi]
mov [edx],al
inc esi
inc edx
Loop L2
L5: mov BYTE PTR [edx],0 ; add NULL byte
jmp L4
L3Err:
mov edx,OFFSET InputTooLong
call WriteString
L4:
popad
mov eax,bytesRead
ret
ReadString endp
;------------------------------------------------------------
SetTextColor PROC
;
; Change the color of all subsequent text output.
; Receives: EAX = attribute. Bits 0-3 are the foreground
; color, and bits 4-7 are the background color.
; Returns: nothing
; Last update: 1/18/02
;------------------------------------------------------------
.data
scrAttrib DWORD ?
.code
pushad
mov scrAttrib,eax ; lowest byte contains the attribute
; Get the console standard output handle:
INVOKE GetStdHandle, STD_OUTPUT_HANDLE
mov [consoleOutHandle],eax
; Set the text color (both background and foreground)
; to white on blue
INVOKE SetConsoleTextAttribute, consoleOutHandle, scrAttrib
popad
ret
SetTextColor endp
;----------------------------------------------------------
Str_compare PROC USES eax edx esi edi,
string1:PTR BYTE,
string2:PTR BYTE
;
; Compare two strings.
; Returns nothing, but the Zero and Carry flags are affected
; exactly as they would be by the CMP instruction.
; Last update: 1/18/02
;-----------------------------------------------------
mov esi,string1
mov edi,string2
L1: mov al,[esi]
mov dl,[edi]
cmp al,0 ; end of string1?
jne L2 ; no
cmp dl,0 ; yes: end of string2?
jne L2 ; no
jmp L3 ; yes, exit with ZF = 1
L2: inc esi ; point to next
inc edi
cmp al,dl ; chars equal?
je L1 ; yes: continue loop
; no: exit with flags set
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -