微机原理课程设计32位汇编学习之四(显示字符串之特殊字体)

来源:互联网 发布:淘宝电商平台技术架构 编辑:程序博客网 时间:2024/04/20 11:24

.386 ;告诉编译器程序使用80386指令集编写的
.model flat,stdcall ;告诉MASM 我们用的内存寻址模式,此处也可以加入stdcall告诉MASM我们所用的参数传递约定
option casemap:none ;告诉编译器要区分标号的大小写

include windows.inc ; windows.inc 包含了 WIN32 编程所需要的常量和结构体的定义。 但是它不包含函数原型的定义
include kernel32.inc ;函数原型声明的头文件 kernel.inc
includelib kernel32.lib ;仅仅是告诉编译器您的程序引用了哪个库
include user32.inc
includelib user32.lib
include gdi32.inc
includelib gdi32.lib

WinMain proto:DWORD,:DWORD,:DWORD,:DWORD

RGB macro red,green,blue
        xor eax,eax
        mov ah,blue
        shl eax,8
        mov ah,green
        mov al,red
endm


.data
 ClassName db "SimpleWinClass",0 ;Windows 类名
 AppName    db "Our First Window",0 ;窗口的名字
 TestString db "Win32 assembly is great and easy!",0
 FontName db "script",0
 
.data? ;存放未进行初始化的变量
 hInstance HINSTANCE ? ;代表应用程序的句柄
 CommandLine LPSTR ? ;保存从命令行传入的参数

.code
start:
 invoke GetModuleHandle,NULL ;查找我们应用程序的句柄,可以把实例句柄看成是您的应用程序的 ID 号,特别注意:WIN32下的实例句柄实际上是您应用程序在内存中的线性地址。WIN32 中函数的函数如果有返回值,那它是通过 eax 寄存器来传递的
 mov hInstance,eax
 invoke GetCommandLine  ;如果您的应用程序不处理命令行那么就无须调用 GetCommandLine,这里只是告诉您如果要调用应该怎么做
 mov CommandLine,eax
 invoke WinMain,hInstance,NULL,CommandLine,SW_SHOWDEFAULT
 invoke ExitProcess,eax
 
 
WinMain proc hInst:HINSTANCE,hPreInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
 
 LOCAL wc:WNDCLASSEX ;伪指令为局部变量在栈中分配内存空间,所有的 LOCAL 指令必须紧跟在 PROC 之后。LOCAL 后跟声明的变量,其形式是 变量名:变量类型。
 LOCAL msg:MSG  ;譬如 LOCAL wc:WNDCLASSEX 即是告诉 MASM 为名字叫 wc 的局部边量在栈中分配长度为 WNDCLASSEX 结构体长度的内存空间,然后我们在用该局部变量是无须考虑堆栈的问题
 LOCAL hwnd:HWND
 
  mov   wc.cbSize,SIZEOF WNDCLASSEX   ;窗口类(window class),一个窗口类就是一个有关窗口的规范,这个规范定义了几个主要的窗口的元素,如:图标、光标、背景色、和负责处理该窗口的函数。您产生一个窗口时就必须要有这样的一个窗口类
  mov   wc.style, CS_HREDRAW or CS_VREDRAW
  mov   wc.lpfnWndProc, OFFSET WndProc
  mov   wc.cbClsExtra,NULL
  mov   wc.cbWndExtra,NULL
  push  hInstance
  pop   wc.hInstance
  mov   wc.hbrBackground,COLOR_WINDOW+1
  mov   wc.lpszMenuName,NULL
         mov   wc.lpszClassName,OFFSET ClassName
         invoke LoadIcon,NULL,IDI_APPLICATION
         mov   wc.hIcon,eax
         mov   wc.hIconSm,eax
         invoke LoadCursor,NULL,IDC_ARROW
         mov   wc.hCursor,eax
         invoke RegisterClassEx, addr wc   ;注册窗口类                    
         invoke CreateWindowEx,NULL,/  ;注册窗口类后,我们将调用CreateWindowEx来产生实际的窗口。请注意该函数有12个参数
          ADDR ClassName,/
                ADDR AppName,/
                WS_OVERLAPPEDWINDOW,/
                CW_USEDEFAULT,/
                CW_USEDEFAULT,/
                CW_USEDEFAULT,/
                CW_USEDEFAULT,/
                NULL,/
                NULL,/
                hInst,/
                NULL
  mov   hwnd,eax  ;调用CreateWindowEx成功后,窗口句柄在eax中。我们必须保存该值以备后用。我们刚刚产生的窗口不会自动显示,所以必须调用 ShowWindow 来按照我们希望的方式来显示该窗口。接下来调用 UpdateWindow 来更新客户区。
  invoke ShowWindow, hwnd,CmdShow
  invoke UpdateWindow, hwnd
 
  .WHILE TRUE
   invoke GetMessage, ADDR msg,NULL,0,0
   .BREAK .IF (!eax)
   invoke TranslateMessage, ADDR msg ;TranslateMessage 函数是一个是实用函数,它从键盘接受原始按键消息,然后解释成 WM_CHAR,在把 WM_CHAR 放入消息队列,由于经过解释后的消息中含有按键的 ASCII 码,这比原始的扫描码好理解得多。如果您的应用程序不处理按键消息的话,可以不调用该函数
   invoke DispatchMessage, ADDR msg  ;DispatchMessage 会把消息发送给负责该窗口过程的函数
  .endw
   mov     eax,msg.wParam
 ret
WinMain endp

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM  ;窗口处理函数
 
 LOCAL hdc:HDC
 LOCAL ps:PAINTSTRUCT
 LOCAL hfont:HFONT
 
 .IF uMsg==WM_DESTROY                          
  invoke PostQuitMessage,NULL
 .ELSEIF uMsg==WM_PAINT
  invoke BeginPaint,hWnd, ADDR ps
  mov    hdc,eax
  invoke CreateFont,24,16,0,0,400,0,0,0,OEM_CHARSET,/
                                       OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,/
                                       DEFAULT_QUALITY,DEFAULT_PITCH or FF_SCRIPT,/
                                       ADDR FontName
                invoke SelectObject, hdc, eax
                mov    hfont,eax
         RGB    200,200,50
         invoke SetTextColor,hdc,eax
         RGB    0,0,255
         invoke SetBkColor,hdc,eax
         invoke TextOut,hdc,0,0,ADDR TestString,SIZEOF TestString
         invoke SelectObject,hdc, hfont 
         invoke EndPaint,hWnd, ADDR ps
           
 .ELSE
  invoke DefWindowProc,hWnd,uMsg,wParam,lParam 
  ret
 .ENDIF
 xor eax,eax     
 ret
WndProc endp


end start

原创粉丝点击