📄 irvine32.asm
字号:
L3: ret
Str_compare ENDP
;---------------------------------------------------------
Str_copy PROC USES eax ecx esi edi,
source:PTR BYTE, ; source string
target:PTR BYTE ; target string
;
; Copy a string from source to target.
; Requires: the target string must contain enough
; space to hold a copy of the source string.
; Last update: 1/18/02
;----------------------------------------------------------
INVOKE Str_length,source ; EAX = length source
mov ecx,eax ; REP count
inc ecx ; add 1 for null byte
mov esi,source
mov edi,target
cld ; direction = up
rep movsb ; copy the string
ret
Str_copy ENDP
;---------------------------------------------------------
Str_length PROC USES edi,
pString:PTR BYTE ; pointer to string
;
; Return the length of a null-terminated string.
; Receives: pString - pointer to a string
; Returns: EAX = string length
; Last update: 1/18/02
;---------------------------------------------------------
mov edi,pString
mov eax,0 ; character count
L1:
cmp byte ptr [edi],0 ; end of string?
je L2 ; yes: quit
inc edi ; no: point to next
inc eax ; add 1 to count
jmp L1
L2: ret
Str_length ENDP
;-----------------------------------------------------------
Str_trim PROC USES eax ecx edi,
pString:PTR BYTE, ; points to string
char:BYTE ; char to remove
;
; Remove all occurences of a given character from
; the end of a string.
; Returns: nothing
; Last update: 1/18/02
;-----------------------------------------------------------
mov edi,pString
INVOKE Str_length,edi ; returns length in EAX
cmp eax,0 ; zero-length string?
je L2 ; yes: exit
mov ecx,eax ; no: counter = string length
dec eax
add edi,eax ; EDI points to last char
mov al,char ; char to trim
std ; direction = reverse
repe scasb ; skip past trim character
jne L1 ; removed first character?
dec edi ; adjust EDI: ZF=1 && ECX=0
L1: mov BYTE PTR [edi+2],0 ; insert null byte
L2: ret
Str_trim ENDP
;---------------------------------------------------
Str_ucase PROC USES eax esi,
pString:PTR BYTE
; Convert a null-terminated string to upper case.
; Receives: pString - a pointer to the string
; Returns: nothing
; Last update: 1/18/02
;---------------------------------------------------
mov esi,pString
L1:
mov al,[esi] ; get char
cmp al,0 ; end of string?
je L3 ; yes: quit
cmp al,'a' ; below "a"?
jb L2
cmp al,'z' ; above "z"?
ja L2
and BYTE PTR [esi],11011111b ; convert the char
L2: inc esi ; next char
jmp L1
L3: ret
Str_ucase ENDP
;------------------------------------------------------
WaitMsg proc
;
; Displays a prompt and waits for the user to press Enter.
; Receives: nothing
; Returns: nothing
;------------------------------------------------------
.data
waitmsgstr DB "Press [Enter] to continue...",0
.code
pushad
CheckInit
mov edx,offset waitmsgstr
call WriteString
NewLine
w1:INVOKE FlushConsoleInputBuffer,consoleInHandle
INVOKE ReadConsole,
consoleInHandle, ; console input handle
OFFSET localBuf, ; pointer to local buffer
READSTRING_BUFSIZE, ; max count
OFFSET bytesRead,
0
cmp bytesRead,2
jnz w1 ;loop until ReadConsole returns 2 bytes read
popad
ret
WaitMsg endp
;------------------------------------------------------
WriteBin proc
;
; Writes a 32-bit integer to standard output in
; binary format.
; Receives: EAX = the integer to write
; Returns: nothing
; Last update: 7/11/01
;------------------------------------------------------
pushad
mov ecx,8 ; number of 4-bit groups in EAX
mov esi,offset buffer
WB1:
push ecx ; save loop count
mov ecx,4 ; 4 bits in each group
WB1A:
shl eax,1 ; shift EAX left into Carry flag
mov byte ptr [esi],'0' ; choose '0' as default digit
jnc WB2 ; if no carry, then jump to L2
mov byte ptr [esi],'1' ; else move '1' to DL
WB2:
inc esi
Loop WB1A ; go to next bit within group
mov byte ptr [esi],' ' ; insert a blank space
inc esi ; between groups
pop ecx ; restore outer loop count
loop WB1 ; begin next 4-bit group
mov byte ptr [esi],0 ; insert null byte at end
mov edx,offset buffer ; display the buffer
call WriteString
popad
ret
WriteBin endp
;------------------------------------------------------
WriteChar proc
;
; Write a character to standard output
; Recevies: AL = character
; Last update: 7/11/01
;------------------------------------------------------
pushad
CheckInit
mov buffer,al
INVOKE WriteConsole,
consoleOutHandle, ; console output handle
offset buffer, ; points to string
1, ; string length
offset bytesWritten, ; returns number of bytes written
0
popad
ret
WriteChar endp
;-----------------------------------------------------
WriteDec proc
;
; Writes an unsigned 32-bit decimal number to
; standard output. Input parameters: EAX = the
; number to write.
; Last update: 7/11/01
;------------------------------------------------------
.data
; There will be as many as 10 digits.
BUFFER_SIZE = 12
bufferL db BUFFER_SIZE dup(?),0
xtable db "0123456789ABCDEF"
.code
pushad
CheckInit
mov ecx,0 ; digit counter
mov edi,offset bufferL
add edi,(BUFFER_SIZE - 1)
mov ebx,10 ; decimal number base
WI1: mov edx,0 ; clear dividend to zero
div ebx ; divide EAX by the radix
xchg eax,edx ; swap quotient, remainder
call AsciiDigit ; convert AL to ASCII
mov [edi],al ; save the digit
dec edi ; back up in buffer
xchg eax,edx ; swap quotient, remainder
inc ecx ; increment digit count
or eax,eax ; quotient = 0?
jnz WI1 ; no, divide again
; Display the digits (CX = count)
WI3:
inc edi
mov edx,edi
call WriteString
WI4:
popad ; restore 32-bit registers
ret
WriteDec endp
;------------------------------------------------------
WriteHex proc
;
; Writes an unsigned 32-bit hexadecimal number to
; standard output.
; Input parameters: EAX = the number to write.
; Last update: 7/11/01
;------------------------------------------------------
DISPLAY_SIZE = 8 ; total number of digits to display
.data
bufferLH db DISPLAY_SIZE dup(?),0
.code
pushad ; save all 32-bit data registers
CheckInit
mov ecx,0 ; digit counter
mov edi,offset bufferLH
add edi,(DISPLAY_SIZE - 1)
mov ebx,16 ; hexadecimal base
WLH1:
mov edx,0 ; clear dividend to zero
div ebx ; divide EAX by the radix
xchg eax,edx ; swap quotient, remainder
call AsciiDigit ; convert AL to ASCII
mov [edi],al ; save the digit
dec edi ; back up in buffer
xchg eax,edx ; swap quotient, remainder
inc ecx ; increment digit count
or eax,eax ; quotient = 0?
jnz WLH1 ; no, divide again
; Insert leading zeros
mov ax,DISPLAY_SIZE
sub ax,cx
jz WLH3 ; display now if no leading zeros required
movzx ecx,ax ; CX = number of leading zeros to insert
WLH2:
mov byte ptr [edi],'0' ; insert a zero
dec edi ; back up
loop WLH2 ; continue the loop
; Display the digits
WLH3:
mov cx,DISPLAY_SIZE
inc edi
mov edx,edi
call WriteString
popad ; restore 32-bit registers
ret
WriteHex endp
;-----------------------------------------------------
WriteInt proc
;
; Writes a 32-bit signed binary integer to standard output
; in ASCII decimal.
; Receives: EAX = the integer
; Returns: nothing
; Comments: Displays a leading sign, no leading zeros.
; Last update: 7/11/01
;-----------------------------------------------------
WI_Bufsize = 12
true = 1
false = 0
.data
buffer_B db WI_Bufsize dup(0),0 ; buffer to hold digits
neg_flag db ?
.code
pushad
CheckInit
mov neg_flag,false ; assume neg_flag is false
or eax,eax ; is AX positive?
jns WIS1 ; yes: jump to B1
neg eax ; no: make it positive
mov neg_flag,true ; set neg_flag to true
WIS1:
mov ecx,0 ; digit count = 0
mov edi,offset buffer_B
add edi,(WI_Bufsize-1)
mov ebx,10 ; will divide by 10
WIS2:
mov edx,0 ; set dividend to 0
div ebx ; divide AX by 10
or dl,30h ; convert remainder to ASCII
dec edi ; reverse through the buffer
mov [edi],dl ; store ASCII digit
inc ecx ; increment digit count
or eax,eax ; quotient > 0?
jnz WIS2 ; yes: divide again
; Insert the sign.
dec edi ; back up in the buffer
inc ecx ; increment counter
mov byte ptr [edi],'+' ; insert plus sign
cmp neg_flag,false ; was the number positive?
jz WIS3 ; yes
mov byte ptr [edi],'-' ; no: insert negative sign
WIS3: ; Display the number
mov edx,edi
call WriteString
popad
ret
WriteInt endp
;--------------------------------------------------------
WriteString proc
;
; Writes a null-terminated string to standard
; output. Input parameter: EDX points to the
; string.
; Last update: 9/7/01
;--------------------------------------------------------
pushad
CheckInit
INVOKE Str_length,edx ; return length of string in EAX
cld ; must do this before WriteConsole
INVOKE WriteConsole,
consoleOutHandle, ; console output handle
edx, ; points to string
eax, ; string length
offset bytesWritten, ; returns number of bytes written
0
popad
ret
WriteString endp
;----------- PRIVATE PROCEDURES --------------------------
;----------------------------------------------------
Initialize proc private
;
; Get the standard console handles for input and output,
; and set a flag indicating that it has been done.
;----------------------------------------------------
pushad
INVOKE GetStdHandle, STD_INPUT_HANDLE
mov [consoleInHandle],eax
INVOKE GetStdHandle, STD_OUTPUT_HANDLE
mov [consoleOutHandle],eax
mov InitFlag,1
popad
ret
Initialize endp
; Convert AL to an ASCII digit. Used by WriteHex & WriteDec
AsciiDigit proc private
push ebx
mov ebx,offset xtable
xlat
pop ebx
ret
AsciiDigit endp
HexByte proc private
; Display the byte in AL in hexadecimal
pushad
mov dl,al
rol dl,4
mov al,dl
and al,0Fh
mov ebx,offset xtable
xlat
mov buffer,al ; save first char
rol dl,4
mov al,dl
and al,0Fh
xlat
mov [buffer+1],al ; save second char
mov [buffer+2],0 ; null byte
mov edx,offset buffer ; display the buffer
call WriteString
popad
ret
HexByte endp
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -