汇编写的一个6KB的小时钟《源码》
时间:2011-08-02
来源:互联网
Assembly code
.386 .model flat,stdcall option casemap:none include windows.inc include gdi32.inc includelib gdi32.lib include user32.inc includelib user32.lib include kernel32.inc includelib kernel32.lib IDC_MAIN equ 1000h ID_TIMER equ 1 .data? hInstance dd ? ;实例句柄 hWinMain dd ? ;窗口句柄 dwCenterX dd ? ;圆心X dwCenterY dd ? ;圆心Y dwRadius dd ? ;半径 .const szClass db 'Clock',0 szWindow db 'Clock',0 szText db '测试HDC函数',0 dwPara180 dw 180 .code _GetCenterProc proc LOCAL @stRect:RECT invoke GetClientRect,hWinMain,addr @stRect mov eax,@stRect.right sub eax,@stRect.left ;宽度 mov ecx,@stRect.bottom sub ecx,@stRect.top ;高度 .if ecx > eax mov edx,eax sub ecx,eax shr ecx,1 ;逻辑右移补0 mov dwCenterX,0 mov dwCenterY,ecx .else mov edx,ecx sub eax,ecx shr eax,1 mov dwCenterX,eax mov dwCenterY,0 .endif shr edx,1 add dwCenterX,edx add dwCenterY,edx mov dwRadius,edx ret _GetCenterProc endp ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>. ;计算时钟圆周上某个角度对应的X坐标 ;x = 圆心X + Sin(角度) * 半径 _CalcX proc _dwDegree,_dwRadius LOCAL @dwReturn fild dwCenterX fild _dwDegree fldpi fmul ;角度*pi fild dwPara180 fdivp st(1),st ;角度*pi/180 fsin ;Sin(角度*pi/180) fild _dwRadius fmul ;半径*sin(角度*pi/180) fadd ;X+半径*sin(角度*pi/180) fistp @dwReturn mov eax,@dwReturn ret _CalcX endp ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>. ;计算时钟圆周上某个角度对应的Y坐标 ;Y = 圆心Y + Sin(角度) * 半径 _CalcY proc _dwDegree,_dwRadius LOCAL @dwReturn fild dwCenterY fild _dwDegree fldpi fmul fild dwPara180 fdivp st(1),st fcos fild _dwRadius fmul fsubp st(1),st fistp @dwReturn mov eax,@dwReturn ret _CalcY endp ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ;按照_dwDegreeInc的步进角度,画_dwRadius为半径的小圆点 _DrawDot proc _hDC,_dwDegreeInc,_dwRadius LOCAL @dwNowDegree,@dwR LOCAL @dwX,@dwY mov @dwNowDegree,0 mov eax,dwRadius sub eax,10 mov @dwR,eax .while @dwNowDegree <= 360 finit ;计算圆点的圆心坐标 invoke _CalcX,@dwNowDegree,@dwR mov @dwX,eax invoke _CalcY,@dwNowDegree,@dwR mov @dwY,eax mov eax,@dwX ;画点 mov ebx,eax mov ecx,@dwY mov edx,ecx sub eax,_dwRadius add ebx,_dwRadius sub ecx,_dwRadius add edx,_dwRadius invoke Ellipse,_hDC,eax,ecx,ebx,edx mov eax,_dwDegreeInc add @dwNowDegree,eax .endw ret _DrawDot endp ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ;画_dwDegree角度的线条,半径 = 时钟半径 - 参数 dwRadiusAdjust _DrawLine proc _hDC,_dwDegree,_dwRadiusAdjust LOCAL @dwR LOCAL @dwX1,@dwY1,@dwX2,@dwY2 mov eax,dwRadius sub eax,_dwRadiusAdjust mov @dwR,eax ;计算线条两端的坐标 invoke _CalcX,_dwDegree,@dwR mov @dwX1,eax invoke _CalcY,_dwDegree,@dwR mov @dwY1,eax add _dwDegree,180 invoke _CalcX,_dwDegree,10 mov @dwX2,eax invoke _CalcY,_dwDegree,10 mov @dwY2,eax invoke MoveToEx,_hDC,@dwX1,@dwY1,NULL invoke LineTo,_hDC,@dwX2,@dwY2 ret _DrawLine endp ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.. _ShowTime proc _hWnd,_hDC LOCAL @stTime:SYSTEMTIME pushad invoke GetLocalTime,addr @stTime invoke _GetCenterProc ;画时钟圆周上的点 invoke GetStockObject,BLACK_BRUSH invoke SelectObject,_hDC,eax invoke _DrawDot,_hDC,360/12,3 ;画12个大圆点 invoke _DrawDot,_hDC,360/60,1 ;画60个小圆点 ;画时钟指针 invoke CreatePen,PS_SOLID,1,0 invoke SelectObject,_hDC,eax invoke DeleteObject,eax movzx eax,@stTime.wSecond mov ecx,360/60 mul ecx ;秒针度数 = 秒 * 360/60 invoke _DrawLine,_hDC,eax,15 invoke CreatePen,PS_SOLID,2,0 invoke SelectObject,_hDC,eax invoke DeleteObject,eax movzx eax,@stTime.wMinute mov ecx,360/60 mul ecx ;分针度数 = 分 * 360/60 invoke _DrawLine,_hDC,eax,20 invoke CreatePen,PS_SOLID,3,0 invoke SelectObject,_hDC,eax invoke DeleteObject,eax movzx eax,@stTime.wHour .if eax >= 12 sub eax,12 .endif mov ecx,360/12 mul ecx movzx ecx,@stTime.wMinute shr ecx,1 add eax,ecx invoke _DrawLine,_hDC,eax,30 invoke GetStockObject,NULL_PEN invoke SelectObject,_hDC,eax invoke DeleteObject,eax popad ret _ShowTime endp ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> _WinProc proc USES ebx edi esi,hWnd,uMsg,wParam,lParam LOCAL @stPain:PAINTSTRUCT mov eax,uMsg .if eax == WM_TIMER invoke InvalidateRect,hWnd,NULL,TRUE .elseif eax == WM_PAINT invoke BeginPaint,hWinMain,addr @stPain invoke _ShowTime,hWnd,eax ;invoke GetClientRect,hWinMain,addr @stRect ;invoke DrawText,@hDC,offset szText,-1,addr @stRect,DT_CENTER or DT_SINGLELINE or DT_VCENTER invoke EndPaint,hWinMain,addr @stPain .elseif eax == WM_CREATE invoke SetTimer,hWnd,ID_TIMER,1000,NULL .elseif eax == WM_CLOSE invoke KillTimer,hWnd,ID_TIMER invoke PostQuitMessage,NULL invoke DestroyWindow,hWinMain .else invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret .endif xor eax,eax ret _WinProc endp _WinMain proc LOCAL @stWnd:WNDCLASSEX LOCAL @stMsg:MSG invoke GetModuleHandle,NULL ;窗口实例句柄 mov hInstance,eax invoke RtlZeroMemory,addr @stWnd,sizeof @stWnd ;在窗口结构初始填充0 invoke LoadIcon,NULL,IDC_MAIN ;加载图标 mov @stWnd.hIcon,eax invoke LoadCursor,NULL,IDC_ARROW ;加载光标 mov @stWnd.hCursor,eax mov @stWnd.cbSize,sizeof WNDCLASSEX ;窗口结构大小 mov @stWnd.style,CS_HREDRAW or CS_VREDRAW ;窗口类型 mov @stWnd.lpfnWndProc,offset _WinProc ;窗口回调函数 push hInstance pop @stWnd.hInstance mov @stWnd.hbrBackground,COLOR_WINDOW + 1 ;窗口背景色 mov @stWnd.lpszClassName,offset szClass ;窗口类名 invoke RegisterClassEx,addr @stWnd ;注册窗口 invoke CreateWindowEx,WS_EX_CLIENTEDGE,offset szClass,offset szWindow,WS_OVERLAPPEDWINDOW,\ 100,100,250,270,NULL,NULL,hInstance,NULL ;创建窗口 mov hWinMain,eax invoke ShowWindow,hWinMain,SW_SHOWNORMAL ;显示窗口 invoke UpdateWindow,hWinMain ;更新窗口 .while TRUE ;窗口消息循环 invoke GetMessage,addr @stMsg,NULL,NULL,NULL .break .if eax == 0 invoke TranslateMessage,addr @stMsg invoke DispatchMessage,addr @stMsg .endw ret _WinMain endp ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> start: call _WinMain invoke ExitProcess,NULL end start
作者: MyLiveIsLost 发布时间: 2011-08-02
???
作者: jiangquan384414031 发布时间: 2011-08-02
楼主这个程序是书上的吗?还是自己写的?
作者: haojiahuo50401 发布时间: 2011-08-02
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28