📄 asmclock.asm
字号:
.386
.model flat,STDCALL
include win32.inc
extrn BeginPaint:PROC
extrn EndPaint:PROC
extrn Ellipse:PROC
extrn CreatePen:PROC
extrn CreateSolidBrush:PROC
extrn GetStockObject:PROC
extrn SelectObject:PROC
extrn DeleteObject:PROC
extrn LineTo:PROC
extrn MoveToEx:PROC
extrn InvalidateRect:PROC
extrn SetTimer:PROC
extrn KillTimer:PROC
extrn GetSystemTime:PROC
extrn CreateWindowExA:PROC
extrn DefWindowProcA:PROC
extrn ExitProcess:PROC
extrn GetMessageA:PROC
extrn TranslateMessage:PROC
extrn DispatchMessageA:PROC
extrn PostQuitMessage:PROC
extrn MessageBoxA:PROC
extrn GetModuleHandleA:PROC
extrn LoadCursorA:PROC
extrn LoadIconA:PROC
extrn RegisterClassA:PROC
extrn ShowWindow:PROC
extrn UpdateWindow:PROC
extrn TextOutA:PROC
; 下面是数据段
.data
tm SYSTEMTIME <?>
text db '00:00:00'
hhcolor dd 004080ffh
mhcolor dd 00ff8080h
scalecolor dd 00ff00ffh
pid30 dq 0.104719755
centerx dd 100.0
centery dd 90.0
scalelen dd 75.0
hourhand dd 40.0
minhand dd 50.0
sechand dd 60.0
handlen dd ?
degree dd ?
newhwnd dd 0
hdc dd 0
lppaint PAINTSTRUCT <?>
msg MSGSTRUCT <?>
wc WNDCLASS <?>
hInst dd 0
titlename db '汇编时钟:陈茂资设计',0
classname db 'ASMCLOCK',0
infotitle db '汇编语言课程设计——时钟',0
author db '作者:陈茂资',10,'班级:计算机(1)班',10,'学号:2002374102',0
; 下面是代码段
.code
start:
push 0
call GetModuleHandleA
mov [hInst],eax
reg_class:
mov [wc.clsStyle],CS_HREDRAW+CS_VREDRAW
mov [wc.clsLpfnWndProc],offset WndProc
mov [wc.clsCbClsExtra],0
mov [wc.clsCbWndExtra],0
mov eax,[hInst]
mov [wc.clsHInstance],eax
push IDI_APPLICATION
push 0
call LoadIconA
mov [wc.clsHIcon],eax
push IDC_ARROW
push 0
call LoadCursorA
mov [wc.clsHCursor],eax
mov [wc.clsHbrBackground],COLOR_WINDOW+1
mov dword ptr [wc.clsLpszMenuName],0
mov dword ptr [wc.clsLpszClassName],offset classname
push offset wc
call RegisterClassA
push 0
push [hInst]
push 0
push 0
push 200 ;高
push 200 ;宽
push 200 ;y
push 300 ;x
push WS_OVERLAPPED+WS_CAPTION+WS_SYSMENU+WS_BORDER
push offset titlename
push offset classname
push 0
call CreateWindowExA
mov [newhwnd],eax
push offset tm
call GetSystemTime
push SW_SHOW
push [newhwnd]
call ShowWindow
push [newhwnd]
call UpdateWindow
push 0
push 1000
push 1
push [newhwnd]
call SetTimer
msg_loop:
push 0
push 0
push 0
push offset msg
call GetMessageA
cmp ax,0
je end_loop
push offset msg
call TranslateMessage
push offset msg
call DispatchMessageA
jmp msg_loop
end_loop:
push [msg.msWPARAM]
call ExitProcess
; 下面是子程序
; Win32要求ebx,edi,esi三个寄存器保留使用,所以在uses后面显示声明以保留
WndProc proc uses ebx edi esi,hwnd:dword,wmsg:dword,wparam:dword,lparam:dword
local i,x,y,pen,tpen,brush:dword
cmp [wmsg],WM_PAINT
je wmpaint
cmp [wmsg],WM_TIMER
je wmtimer
cmp [wmsg],WM_DESTROY
je wmdestroy
jmp defwndproc
wmpaint:
push offset lppaint
push [hwnd]
call BeginPaint
mov [hdc],eax
; 下面绘制渐变背景
push 0
call CreateSolidBrush
mov brush,eax
push eax
push [hdc]
call SelectObject
push eax
push NULL_PEN
call GetStockObject
mov tpen,eax
push eax
push [hdc]
call SelectObject
push eax
mov i,80
next:
push brush
call DeleteObject
mov edx,i
mov cl,16
shl edx,cl
mov eax,00aff0f0h
add eax,edx
push eax
call CreateSolidBrush
mov brush,eax
push eax
push [hdc]
call SelectObject
mov edx,i
add edx,90
push edx
mov edx,i
add edx,100
push edx
mov edx,90
sub edx,i
push edx
mov edx,100
sub edx,i
push edx
push [hdc]
call Ellipse
dec i
jnz next
push [hdc]
call SelectObject
push [hdc]
call SelectObject
; 下面画60个刻度
mov i,60
next2:
fild i
fmul pid30
fsin
fmul scalelen
fadd centery
fistp y
add y,2
push y
fild i
fmul pid30
fcos
fmul scalelen
fadd centerx
fistp x
add x,2
push x
sub y,4
push y
sub x,4
push x
push [hdc]
call Ellipse
dec i
jnz next2
; 下面画12个正点刻度
push scalecolor
call CreateSolidBrush
push eax
push [hdc]
call SelectObject
push eax
mov i,12
next3:
push i
mov eax,i
mov ecx,5
mul ecx
mov i,eax
fild i
fmul pid30
fsin
fmul scalelen
fadd centery
fistp y
add y,3
push y
fild i
fmul pid30
fcos
fmul scalelen
fadd centerx
fistp x
add x,3
push x
sub y,6
push y
sub x,6
push x
push [hdc]
call Ellipse
pop i
dec i
jnz next3
call SelectObject
; 下面将整数转为字符串存在text中并打印
mov ax,tm.wHour
add ax,8
xor dx,dx
mov cx,24
div cx
mov ax,dx
xor dx,dx
mov cx,10
div cx
add ax,'0'
add dx,'0'
mov text[0],al
mov text[1],dl
mov ax,tm.wMinute
xor dx,dx
mov cx,10
div cx
add ax,'0'
add dx,'0'
mov text[3],al
mov text[4],dl
mov ax,tm.wSecond
xor dx,dx
mov cx,10
div cx
add ax,'0'
add dx,'0'
mov text[6],al
mov text[7],dl
push 8
push offset text
push 5
push 5
push [hdc]
call TextOutA
; 下面绘制时针
push hhcolor
push 4
push 0
call CreatePen
mov pen,eax
push eax
push [hdc]
call SelectObject
push eax
mov ax,tm.wHour
movzx eax,ax
add eax,8
xor edx,edx
mov ecx,12
div ecx
mov eax,edx
mov ecx,5
mul ecx
push eax
mov ax,tm.wMinute
movzx eax,ax
xor edx,edx
mov ecx,12
div ecx
pop ecx
add eax,ecx
mov degree,eax
mov eax,hourhand
mov handlen,eax
call DrawHand
push pen
call DeleteObject
; 下面绘制分针
push mhcolor
push 2
push 0
call CreatePen
push eax
push [hdc]
call SelectObject
mov ax,tm.wMinute
movzx eax,ax
mov degree,eax
mov eax,minhand
mov handlen,eax
call DrawHand
push [hdc]
call SelectObject
; 下面绘制秒针
mov ax,tm.wSecond
movzx eax,ax
mov degree,eax
mov eax,sechand
mov handlen,eax
call DrawHand
; 下面结束绘图
push offset lppaint
push [hwnd]
call EndPaint
mov eax,0
jmp finish
wmtimer:
push offset tm
call GetSystemTime
push 0
push 0
push [hwnd]
call InvalidateRect
mov eax,0
jmp finish
defwndproc:
push [lparam]
push [wparam]
push [wmsg]
push [hwnd]
call DefWindowProcA
jmp finish
wmdestroy:
push 1
push [hwnd]
call KillTimer
push MB_ICONASTERISK
push offset infotitle
push offset author
push [hwnd]
call MessageBoxA
push 0
call PostQuitMessage
mov eax,0
finish:
ret
WndProc endp
; 此子程序画时钟上的针
; 入口参数:handlen为针的长度,degree指示60个刻度中的一个
DrawHand proc near
local out:dword
push 0
push 90
push 100
push [hdc]
call MoveToEx
fild degree
fmul pid30
fcos
fmul handlen
fsubr centery
fistp out
push out
fild degree
fmul pid30
fsin
fmul handlen
fadd centerx
fistp out
push out
push [hdc]
call LineTo
ret
DrawHand endp
end start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -