代码来自于《Intel汇编语言程序设计》(第四版)第10章----结构和宏。
如果要显示系统时间,MS-Windows为我们提供了两个函数,用来设置光标位置的控制台函数和现实系统时间的函数。使用这两个函数之前,需要首先定义两个预定义的结构:
COORD STRUCT
X WORD ?
Y WORD ?
COORD ENDS
SYSTEMTIME STRUCT
wYear WORD ?
wMonth WORD ?
wDayOfWeek WORD ?
wDay WORD ?
wHour WORD ?
wMinute WORD ?
wSecond WORD ?
wMillisecond WORD ?
SYSTEMTIME ENDS
在原书中这两个结构体在SmallWin.inc文件中定义,而SmallWin.inc文件位于编译器的INCLUDE目录中,Irvine32.inc引用了SmallWin.inc文件。
我们来看看一下返回当前系统时间并在指定的屏幕位置显示的程序清单:
TITLE Structures (ShowTime.asm)
INCLUDE Irvine32.inc
.data
sysTime SYSTEMTIME <>
XYPos COORD <10,5>
consoleHandle DWORD ?
colonStr BYTE ":",0
.code
main PROC
; Get the standard output handle for the Win32 Console.
INVOKE GetStdHandle , STD_OUTPUT_HANDLE
mov consoleHandle, eax
; Set the cursor position and get the system time.
INVOKE SetConsoleCursorPosition , consoleHandle , XYPos
INVOKE GetLocalTime , ADDR sysTime
; Display the system time ( hh : mm : ss).
movzx eax,sysTime.wHour ; hours
call WriteDec
mov edx,offset colonStr ; ":"
call WriteString
movzx eax,sysTime.wMinute ; Minutes
call WriteDec
mov edx,offset colonStr ; ":"
call WriteString
movzx eax,sysTime.wSecond ; Seconds
call WriteDec
call Crlf
call Crlf
call WaitMsg ; "Press Enter..."
exit
main ENDP
END main
程序中使用的定义来自于SmallWin.inc。
STD_OUTPUT_HANDLE EQU -11
SYSTEMTIME STRUCT . . . (参考以上的定义)
COORD STRUCT . . . (参考以上的定义)
GetStdHandle PROTO,
nStdHandle:DWORD
GetLocalTime PROTO,
lpSystemTime:PTR SYSTEMTIME
SetConsoleCursorPosition PROTO,
nStdHandle:DWORD,
coords:COORD
首先,要想获取系统时间,可以调用MS-Windows的GetLocalTime函数并向他传递SYSTEMTIME结构的地址:
.data
sysTime SYSTEMTIME <>
.code
INVOKE GetLocalTime , ADDR sysTime
此时,函数GetLocalTime 将把系统时间返回保存至sysTime中。
然后,就可以返回某一时间值,例如:
movzx eax,sysTime .wYear
call WriteDec
便返回了年的时间,并且打印出来。
当Win32程序想要产生屏幕输出时,需要调用GetStdHandle函数返回标准的控制台输出句柄(一个整数):
.data
consoleHandle DWORD ?
.code
INVOKE GetStdHandle , STD_OUTPUT_HANDLE
mov consoleHandle,eax
此时,调用GetStdHandle 函数,并传递STD_OUTPUT_HANDLE常量,将返回标准控制台的句柄到eax中。
得到标准输出句柄之后,接着要设置屏幕光标位置,可以调用MS-Windows的SetConsoleCursorPosition函数,这个函数需要一个控制台句柄和一个COORD结构变量作为参数:
.data
XYPos COORD <10,5>
.code
INVOKE SetConsoleCursorPosition,consoleHandle,XYPos
在代码中使用的指令MOVZX (move with zero-extend)指令用于将源操作数的内容拷贝到目的操作数中,并将该值零扩展至16位或32位。该指令仅适用于无符号整数,例如:
mov bx,0A69Bh
movzx eax,bx ; EAX = 0000A69Bh
movzx edx,bl ; EDX = 0000009Bh
movzx cx,bl ; CX = 009Bh