📄 irvine32.asm
字号:
Title Irvine32 Link Library Source Code (Irvine32.asm)
Comment @
This library was created exlusively for use with the book,
"Assembly Language for Intel-Based Computers",
by Kip R. Irvine, 2002.
Copyright 2002, Prentice-Hall Incorporated. No part of this file may be
reproduced, in any form or by any other means, without permission in writing
from the publisher.
Updates to this file will be posted at the book's site:
www.nuvisionmiami.com/books/asm
Acknowledgements:
------------------------------
Most of the code in this library was written by Kip Irvine.
Special thanks to Gerald Cahill for his many insights, suggestions, and bug fixes!
Alphabetical Listing of Procedures
----------------------------------
(Unless otherwise marked, all procedures are documented in Chapter 5.)
ClrScr
Crlf
Delay
DumpMem
DumpRegs
GetCommandTail
GetDateTime Chapter 11
GetMseconds
Gotoxy
IsDigit
Random32
Randomize
RandomRange
ReadChar
ReadHex
ReadInt
ReadString
SetTextColor
Str_compare Chapter 9
Str_copy Chapter 9
Str_length Chapter 9
Str_trim Chapter 9
Str_ucase Chapter 9
WaitMsg
WriteBin
WriteChar
WriteDec
WriteHex
WriteInt
WriteString
Implementation Notes:
--------------------
1. The Windows Sleep function changes ECX. Remember to save and restore all
registers before calling other windows functions.
2. The WriteConsole API function will not work if the Direction flag is set.
@
INCLUDE Irvine32.inc ; function prototypes for this library
INCLUDE Macros.inc ; macro defintions
;-------------------------------------
ShowFlag macro flagName,shiftCount
LOCAL flagStr, flagVal, L1
;
; Display a single CPU flag value
; Directly accesses the eflags variable in Irvine16.asm/Irvine32.asm
; (This macro cannot be placed in Macros.inc)
;-------------------------------------
.data
flagStr DB " &flagName="
flagVal DB ?,0
.code
push eax
push edx
mov eax,eflags ; retrieve the flags
mov flagVal,'1'
shr eax,shiftCount ; shift into carry flag
jc L1
mov flagVal,'0'
L1:
mov edx,offset flagStr ; display flag name and value
call WriteString
pop edx
pop eax
endm
;---------------------------------------------------
ShowRegister MACRO regName, regValue
LOCAL tempStr
;
; Display a register's name and contents.
;---------------------------------------------------
.data
tempStr BYTE " ®Name=",0
.code
push eax
; Display the register name
push edx
mov edx,OFFSET tempStr
call WriteString
pop edx
; Display the register contents
mov eax,regValue
call WriteHex
pop eax
ENDM
;********************* SHARED DATA AREA **********************
.data ; initialized data
InitFlag DB 0 ; initialization flag
.data? ; uninitialized data
consoleInHandle dd ? ; handle to standard input device
consoleOutHandle dd ? ; handle to standard output device
bytesWritten dd ? ; number of bytes written
eflags DWORD ?
buffer DB 512 dup(?)
bufferMax = ($ - buffer)
bytesRead DD ?
sysTime SYSTEMTIME <> ; system time structure
.code
;---------------------------------------------------
; Check to see if the console handles have been initialized
CheckInit macro
Local exit
cmp InitFlag,0
jne exit
call Initialize
exit:
endm
;--------------------------------------------------
ClrScr proc
;
; Clear the screen by writing blanks to all positions
; Receives: nothing
; Returns: nothing
; Last update: 7/11/01
;--------------------------------------------------------
.data
blanks DB (80 * 25) DUP(' ')
blankSize = ($ - blanks)
upperLeft COORD <0,0>
.code
pushad
CheckInit
INVOKE SetConsoleCursorPosition, consoleOutHandle, upperLeft
INVOKE WriteConsole,
consoleOutHandle, ; console output handle
offset blanks, ; string pointer
blankSize, ; string length
offset bytesWritten, ; returns number of bytes written
0
INVOKE SetConsoleCursorPosition, consoleOutHandle, upperLeft
popad
ret
ClrScr endp
;-----------------------------------------------------
Crlf proc
;
; Writes a carriage return / linefeed
; sequence (0Dh,0Ah) to standard output.
;-----------------------------------------------------
CheckInit
NewLine ; invoke a macro
ret
Crlf endp
;------------------------------------------------------
Delay proc
;
; THIS FUNCTION IS NOT IN THE IRVINE16 LIBRARY
; Delay (pause) the current process for a given number
; of milliseconds.
; Receives: EAX = number of milliseconds
; Returns: nothing
; Last update: 7/11/01
;------------------------------------------------------
pushad
INVOKE Sleep,eax
popad
ret
Delay endp
;---------------------------------------------------
DumpMem proc
LOCAL unitsize:dword, byteCount:word
;
; Writes a range of memory to standard output
; in hexadecimal.
; Receives: ESI = starting offset, ECX = number of units,
; EBX = unit size (1=byte, 2=word, or 4=doubleword)
; Returns: nothing
; Last update: 7/11/01
;---------------------------------------------------
.data
oneSpace DB ' ',0
dumpPrompt DB 13,10,"Dump of offset ",0
dashLine DB "-------------------------------",13,10,0
.code
pushad
mov edx,offset dumpPrompt
call WriteString
mov eax,esi ; get memory offset to dump
call WriteHex
NewLine
mov edx,offset dashLine
call WriteString
mov byteCount,0
mov unitsize,ebx
cmp ebx,4 ; select output size
je L1
cmp ebx,2
je L2
jmp L3
; 32-bit doubleword output
L1:
mov eax,[esi]
call WriteHex
WriteSpace 2
add esi,ebx
Loop L1
jmp L4
; 16-bit word output
L2:
mov ax,[esi] ; get a word from memory
ror ax,8 ; display high byte
call HexByte
ror ax,8 ; display low byte
call HexByte
WriteSpace 1 ; display 1 space
add esi,unitsize ; point to next word
Loop L2
jmp L4
; 8-bit byte output, 16 bytes per line
L3:
mov al,[esi]
call HexByte
inc byteCount
WriteSpace 1
inc esi
; if( byteCount mod 16 == 0 ) call Crlf
mov dx,0
mov ax,byteCount
mov bx,16
div bx
cmp dx,0
jne L3B
NewLine
L3B:
Loop L3
jmp L4
L4:
NewLine
popad
ret
DumpMem endp
;---------------------------------------------------
DumpRegs PROC
;
; Displays EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP in
; hexadecimal. Also displays the Zero, Sign, Carry, and
; Overflow flags.
; Receives: nothing.
; Returns: nothing.
; Last update: 8/23/01
;
; Warning: do not create any local variables or stack
; parameters, because they will alter the EBP register.
;---------------------------------------------------
.data
saveIP DWORD ?
saveESP DWORD ?
.code
pop saveIP ; get current EIP
mov saveESP,esp ; save ESP's value at entry
push saveIP ; replace it on stack
push eax ; save EAX (restore on exit)
pushfd ; push extended flags
pushfd ; push flags again, and
pop eflags ; save them in a variable
NewLine
ShowRegister EAX,EAX
ShowRegister EBX,EBX
ShowRegister ECX,ECX
ShowRegister EDX,EDX
NewLine
ShowRegister ESI,ESI
ShowRegister EDI,EDI
ShowRegister EBP,EBP
mov eax,saveESP
ShowRegister ESP,EAX
NewLine
mov eax,saveIP
ShowRegister EIP,EAX
mov eax,eflags
ShowRegister EFL,EAX
; Show the flags (using the eflags variable)
ShowFlag CF,1
ShowFlag SF,8
ShowFlag ZF,7
ShowFlag OF,12
NewLine
NewLine
popfd
pop eax
ret
DumpRegs endp
;------------------------------------------------------------
GetCommandTail PROC
;
; Copies the program command line into a buffer.
; Receives: EDX points to a buffer that will receive the data.
; Returns: nothing
;-------------------------------------------------------------
pushad
INVOKE GetCommandLine ; Win32 API function
; returns pointer in EAX
; Copy the command-line string to the array
; pointed to by EDX.
mov esi,eax
L1: mov al,[esi]
mov [edx],al
cmp al,0 ; null byte found?
je L2 ; exit loop
inc esi
inc edx
jmp L1
L2: popad
ret
GetCommandTail ENDP
;--------------------------------------------------
GetDateTime PROC,
pStartTime:PTR QWORD
LOCAL flTime:FILETIME
;
; Gets and saves the current local date/time as a
; 64-bit integer (in the Win32 FILETIME format).
;--------------------------------------------------
; Get the system local time
INVOKE GetLocalTime,
ADDR sysTime
; Convert the SYSTEMTIME to FILETIME
INVOKE SystemTimeToFileTime,
ADDR sysTime,
ADDR flTime
; Copy the FILETIME to a Quadword
mov esi,pStartTime
mov eax,flTime.loDateTime
mov DWORD PTR [esi],eax
mov eax,flTime.hiDateTime
mov DWORD PTR [esi+4],eax
ret
GetDateTime ENDP
;---------------------------------------------------
GetMseconds PROC USES ebx
LOCAL hours:DWORD, min:DWORD, sec:DWORD
;
; Calculate milliseconds past midnight.
; Receives: nothing
; Returns: EAX = ((hours * 3600) + (minutes * 60) + seconds) * 1000 + milliseconds
;---------------------------------------------------
INVOKE GetLocalTime,offset sysTime
; convert hours to seconds
movzx eax,sysTime.wHour
mov ebx,3600
mul ebx
mov hours,eax
; convert minutes to seconds
movzx eax,sysTime.wMinute
mov ebx,60
mul ebx
mov min,eax
; add seconds to total seconds
movzx eax,sysTime.wSecond
mov sec,eax
; multiply seconds by 1000
mov eax,hours
add eax,min
add eax,sec
mov ebx,1000
mul ebx
; add milliseconds to total
movzx ebx,sysTime.wMilliseconds
add eax,ebx
ret
GetMseconds ENDP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -