zoukankan      html  css  js  c++  java
  • windows10 安装NASM

    在编写nasm时数字默认为10进制

    x86控制台程序

    objexe.asm:

    ; equ 定义常量
    STD_OUTPUT_HANDLE EQU -11
    
    ; 导入外部符号, Windows API函数,已修饰
    extern _GetStdHandle@4              
    extern _WriteFile@20
    extern _ExitProcess@4
    
    global Start                                    ; 导出符号。 入口点
    
    section .data                                   ; 初始化数据段
     Message        db "hello.", 0Dh, 0Ah           ; 0Dh 0Ah 回车/换行
     MessageLength  EQU $ - Message                 ; $ - Message地址 == Message长度
    
    section .bss                                    ; 未初始化的数据段
     Written        resd 1                          ; 一个dword的大小,4字节,32位
    
    section .text                                   ; 代码段
    Start:
     push  STD_OUTPUT_HANDLE
     call  _GetStdHandle@4				;检索指定标准设备
    
     push  0                                        ; 第5个参数
     push  Written                                  ; 第4个参数
     push  MessageLength                            ; 第3个参数
     push  Message                                  ; 第2个参数
     push  EAX                        		; 第1个参数 i/o句柄
     call  _WriteFile@20                            ; 调用函数,将数据写入指定的文件或输入/输出(I/O)设备
     
     push  0
     call  _ExitProcess@4
    
    >nasm -f win32 objexe.asm
    >golink /entry:Start /console kernel32.dll user32.dll objexe.obj
    >objexe.exe
    hello.
    

    x64控制台程序

    STD_OUTPUT_HANDLE EQU -11
    
    extern GetStdHandle
    extern WriteFile
    extern ExitProcess
    
    global Start
    
    section .data
     Message        db "hello x64.", 0Dh, 0Ah
     MessageLength  EQU $-Message
    
    section .bss
    ; 结构对齐
    ; 最大成员为8字节
    ; 该结构应从8整除的内存位置开始,alignb 8确保
    ; 如果其中有个成员为4字节,那么你要保证接下来的8字节成员自然对齐,那么就需要加padding
    ; 最后: 总长度要可以被8整除,不能整除就加padding 16/8=2
    alignb 8
     StandardHandle resq 1
     Written        resq 1
     
     ; test resd 1 ;4字节成员
     ; padding1 resd 1 ;加padding对齐
    
    section .text
    Start:
     sub   RSP, 8                                   ; 将堆栈对齐为16个字节的倍数
    
     sub   RSP, 32                                  ; 阴影空间32字节
     mov   ECX, STD_OUTPUT_HANDLE
     call  GetStdHandle
     
     mov   qword [REL StandardHandle], RAX
     add   RSP, 32                                  ; 删除32个字节
    
     ; 4个参数每个8字节就是32,外加一个堆栈上的就是8字节
     ; 函数在内部会把这些参数放在堆栈,寄存器就那么几个
     ; 最后+8使堆栈对齐16个字节的倍数 48/16=3  40/16=2.5,能整除就是对齐
     sub   RSP, 32 + 8 + 8                          ; 阴影空间+第5个参数+对齐堆栈
                                                    ; to a multiple of 16 bytes
     mov   RCX, qword [REL StandardHandle]          ; 第1个参数
     lea   RDX, [REL Message]                       ; 第2个参数
     mov   R8, MessageLength                        ; 第3个参数
     lea   R9, [REL Written]                        ; 第4个参数
     mov   qword [RSP + 32], 0                   	; 第5个参数
     call  WriteFile
     add   RSP, 48                                  ; 删除48个字节
    
     xor   ECX, ECX									;异或 ECX = 0
     call  ExitProcess
    
    >nasm -f win64 objexe.asm
    >golink /entry:Start /console kernel32.dll user32.dll objexe.obj
    >objexe.exe
    hello x64.
    

    x86 MessageBox

    extern MessageBoxA
    extern ExitProcess
    
    global Start
    
    section .data
    	text db "hello.",0
    	title db "title",0
    	
    section .text
    Start:
    	; int MessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
    	push 0x00000001
    	push title
    	push text
    	push 0
    	call MessageBoxA
    	
    	; 如果点击了取消,就继续弹
    	cmp eax,2
    	je Start
    	
    	; 退出
    	push 0
    	call ExitProcess
    
    >nasm -f win32 objexe.asm
    >golink /entry:Start kernel32.dll user32.dll objexe.obj
    >objexe.exe
    

    x64 MessageBox

    extern MessageBoxA
    extern ExitProcess
    
    global Start
    
    section .data
    	text db "hello.",0
    	title db "title",0
    	
    section .text
    Start:
    	sub rsp, 8
    	sub rsp, 32
    
    _msgbox:
    	; int MessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
    	xor ecx,ecx
    	lea edx,[text]
    	lea r8,[title]
    	mov r9,0x01
    	call MessageBoxA
    
    	; 如果点击了取消,就继续弹
    	cmp rax,0x2
    	je _msgbox
    	
    	add rsp, 32
    
    _exit:
    	xor ecx,ecx
    	call ExitProcess
    
    >nasm -f win64 objexe.asm
    >golink /entry:Start kernel32.dll user32.dll objexe.obj
    >objexe.exe
    

    x86 基本窗口

    WindowWidth         EQU 640
    WindowHeight        EQU 480
    
    extern _CreateWindowExA@48
    extern _DefWindowProcA@16
    extern _DispatchMessageA@4
    extern _ExitProcess@4
    extern _GetMessageA@16
    extern _GetModuleHandleA@4
    extern _IsDialogMessageA@8
    extern _LoadImageA@24
    extern _PostQuitMessage@4
    extern _RegisterClassExA@4
    extern _ShowWindow@8
    extern _TranslateMessage@4
    extern _UpdateWindow@4
    
    global Start
    
    section .data
     WindowName db "Basic Window 32", 0
     ClassName  db "Window", 0
    
    section .bss
     hInstance resd 1
    
    section .text
    Start:
    
     ; https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getmodulehandlea
     push  0
     call  _GetModuleHandleA@4
     mov   dword [hInstance], EAX ; 保存返回的模块句柄
    
     call  WinMain
    
    .Exit:
     push  0
     call  _ExitProcess@4
    
    WinMain:
     push  EBP
     mov   EBP, ESP
     sub   ESP, 80                                  ; 80个字节的局部变量的空间
    
    ; define 指令用于分配存储空间。它可以用于保留以及初始化一个或多个字节。
    ; https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-wndclassexa
    %define wc                 EBP - 80             ; WNDCLASSEX结构(包含窗口类信息). 48字节
    %define wc.cbSize          EBP - 80
    %define wc.style           EBP - 76
    %define wc.lpfnWndProc     EBP - 72
    %define wc.cbClsExtra      EBP - 68
    %define wc.cbWndExtra      EBP - 64
    %define wc.hInstance       EBP - 60
    %define wc.hIcon           EBP - 56
    %define wc.hCursor         EBP - 52
    %define wc.hbrBackground   EBP - 48
    %define wc.lpszMenuName    EBP - 44
    %define wc.lpszClassName   EBP - 40
    %define wc.hIconSm         EBP - 36
    
    %define msg                EBP - 32             ; MSG结构. 28字节
    %define msg.hwnd           EBP - 32             ; 不必拆分每个成员
    %define msg.message        EBP - 28             ; 在这种情况下,但它显示了每个
    %define msg.wParam         EBP - 24             ; 成员在堆栈上
    %define msg.lParam         EBP - 20
    %define msg.time           EBP - 16
    %define msg.pt.x           EBP - 12
    %define msg.pt.y           EBP - 8
    
    %define hWnd               EBP - 4
    
     mov   dword [wc.cbSize], 48                    ; [EBP - 80]
     mov   dword [wc.style], 2 | 1 | 2000h  		; [EBP - 76]
     mov   dword [wc.lpfnWndProc], WndProc          ; [EBP - 72]
     mov   dword [wc.cbClsExtra], 0              ; [EBP - 68]
     mov   dword [wc.cbWndExtra], 0              ; [EBP - 64]
     mov   EAX, dword [hInstance]                   ; Global
     mov   dword [wc.hInstance], EAX                ; [EBP - 60]
    
     ; 加载图标,光标,动画光标或位图
     push  8000h
     push  0
     push  0
     push  1	;加载一个图标
     push  7F00h	
     push  0
     call  _LoadImageA@24                           ; Large program icon
     mov   dword [wc.hIcon], EAX                    ; [EBP - 56]
    
     push  8000h
     push  0
     push  0
     push  2	;加载游标
     push  7F00h
     push  0
     call  _LoadImageA@24                           ; Cursor
     mov   dword [wc.hCursor], EAX                  ; [EBP - 52]
    
     mov   dword [wc.hbrBackground], 5 + 1  ; [EBP - 48]
     mov   dword [wc.lpszMenuName], 0            ; [EBP - 44]
     mov   dword [wc.lpszClassName], ClassName      ; [EBP - 40]
    
     push  8000h
     push  0
     push  0
     push  1
     push  7F00h
     push  0
     call  _LoadImageA@24                           ; Small program icon
     mov   dword [wc.hIconSm], EAX                  ; [EBP - 36]
    
     ; 注册一个窗口类,供以后在对CreateWindow或CreateWindowEx函数的调用中使用
     ;https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexa
     lea   EAX, [wc]                                ; [EBP - 80]
     push  EAX
     call  _RegisterClassExA@4
    
    ;创建具有扩展窗口样式的重叠窗口
    ;https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexa
     push  0
     push  dword [hInstance]                        ; Global
     push  0
     push  0
     push  WindowHeight
     push  WindowWidth
     push  0	;y
     push  0	;x
     push  0CF0000h		;窗口样式 https://docs.microsoft.com/en-us/windows/win32/winmsg/window-styles
     push  WindowName                               ; Global
     push  ClassName                                ; Global
     push  2000000h
     call  _CreateWindowExA@48
     mov   dword [hWnd], EAX                        ; [EBP - 4] 新窗口句柄
    
    ;设置指定窗口的显示状态, 1 激活并显示一个窗口
     push  1
     push  dword [hWnd]                             ; [EBP - 4]
     call  _ShowWindow@8
    
     push  dword [hWnd]                             ; [EBP - 4]
     call  _UpdateWindow@4
    
    .MessageLoop:
    
    ;从调用线程的消息队列中检索消息
     lea   EAX, [msg]                               ; [EBP - 32]
     push  0
     push  0
     push  0
     push  EAX
     call  _GetMessageA@16
     cmp   EAX, 0
     je    .Done
    
    ;确定是否将消息用于指定的对话框,如果是,则处理该消息
     lea   EAX, [msg]                               ; [EBP - 32]
     push  EAX
     push  dword [hWnd]                             ; [EBP - 4]
     call  _IsDialogMessageA@8                      ; For keyboard strokes
     cmp   EAX, 0									; 如果消息已处理,则返回值为非零
     jne   .MessageLoop                             ; 跳过TranslateMessage和DispatchMessage
    
    ;将虚拟键消息转换为字符消息。字符消息将发布到调用线程的消息队列中
    ;以在线程下次调用GetMessage或PeekMessage函数时读取。
     lea   EAX, [msg]                               ; [EBP - 32]
     push  EAX
     call  _TranslateMessage@4
    
    ;将消息调度到窗口过程。它通常用于调度由GetMessage函数检索的消息
     lea   EAX, [msg]                               ; [EBP - 32]
     push  EAX
     call  _DispatchMessageA@4
     jmp   .MessageLoop
    
    .Done:
     mov   ESP, EBP                                 ; Remove the stack frame
     pop   EBP
     xor   EAX, EAX
     ret
    
    ; 回调函数
    WndProc:
     push  EBP                                      ; Set up a Stack frame
     mov   EBP, ESP
    
    ; 获取参数
    %define hWnd    EBP + 8                         ; Location of the 4 passed parameters from
    %define uMsg    EBP + 12                        ; the calling function
    %define wParam  EBP + 16                        ; We can now access these parameters by name
    %define lParam  EBP + 20
    
     cmp   dword [uMsg], 2                 ; [EBP + 12]
     je    _WMDESTROY
    
    _DefaultMessage:
     push  dword [lParam]                           ; [EBP + 20]
     push  dword [wParam]                           ; [EBP + 16]
     push  dword [uMsg]                             ; [EBP + 12]
     push  dword [hWnd]                             ; [EBP + 8]
     call  _DefWindowProcA@16
    
     mov   ESP, EBP                                 ; Remove the stack frame
     pop   EBP
     ret   16                                       ; 内平栈,这就涉及到调用约定,被调用的函数需要处理堆栈
    
    _WMDESTROY:
    ;向系统指示线程已请求终止(退出)
     push  0
     call  _PostQuitMessage@4
    
     xor   EAX, EAX                                 ; return 0
     mov   ESP, EBP                                 ; Remove the stack frame
     pop   EBP
     ret   16                                       ; 内平栈
    
    >nasm -f win32 objexe.asm
    >golink /entry:Start kernel32.dll user32.dll  objexe.obj
    >objexe.exe
    

    x64 基本窗口

                                                    ; Basic Window, 64 bit. V1.02
    COLOR_WINDOW        EQU 5                       ; Constants
    CS_BYTEALIGNWINDOW  EQU 2000h
    CS_HREDRAW          EQU 2
    CS_VREDRAW          EQU 1
    CW_USEDEFAULT       EQU 80000000h
    IDC_ARROW           EQU 7F00h
    IDI_APPLICATION     EQU 7F00h
    IMAGE_CURSOR        EQU 2
    IMAGE_ICON          EQU 1
    LR_SHARED           EQU 8000h
    NULL                EQU 0
    SW_SHOWNORMAL       EQU 1
    WM_DESTROY          EQU 2
    WS_EX_COMPOSITED    EQU 2000000h
    WS_OVERLAPPEDWINDOW EQU 0CF0000h
    
    WindowWidth         EQU 640
    WindowHeight        EQU 480
    
    extern CreateWindowExA                          ; Import external symbols
    extern DefWindowProcA                           ; Windows API functions, not decorated
    extern DispatchMessageA
    extern ExitProcess
    extern GetMessageA
    extern GetModuleHandleA
    extern IsDialogMessageA
    extern LoadImageA
    extern PostQuitMessage
    extern RegisterClassExA
    extern ShowWindow
    extern TranslateMessage
    extern UpdateWindow
    
    global Start                                    ; Export symbols. The entry point
    
    section .data                                   ; Initialized data segment
     WindowName  db "Basic Window 64", 0
     ClassName   db "Window", 0
    
    section .bss                                    ; Uninitialized data segment
     alignb 8
     hInstance resq 1
    
    section .text                                   ; Code segment
    Start:
     sub   RSP, 8                                   ; Align stack pointer to 16 bytes
    
     ; GetModuleHandleA 只有一个参数为什么还分配32字节的阴影空间
     ; win64函数约定,假定您已经分配了32个字节的堆栈空间来存储四个参数寄存器
     ; 自己写的函数可以不用遵守
     sub   RSP, 32                                  ; 32 bytes of shadow space
     xor   ECX, ECX
     call  GetModuleHandleA
     mov   qword [REL hInstance], RAX
     add   RSP, 32                                  ; Remove the 32 bytes
    
     call  WinMain
    
    .Exit:
     xor   ECX, ECX
     call  ExitProcess
    
    WinMain:
     push  RBP                                      ; Set up a stack frame
     mov   RBP, RSP
     sub   RSP, 136 + 8                             ; 局部变量为136个字节
                                                    ; a multiple of 16 (for Windows API functions),
                                                    ; the + 8 takes care of this.
    
    %define wc                 RBP - 136            ; WNDCLASSEX structure, 80 bytes
    %define wc.cbSize          RBP - 136            ; 4 bytes. Start on an 8 byte boundary
    %define wc.style           RBP - 132            ; 4 bytes
    %define wc.lpfnWndProc     RBP - 128            ; 8 bytes
    %define wc.cbClsExtra      RBP - 120            ; 4 bytes
    %define wc.cbWndExtra      RBP - 116            ; 4 bytes
    %define wc.hInstance       RBP - 112            ; 8 bytes
    %define wc.hIcon           RBP - 104            ; 8 bytes
    %define wc.hCursor         RBP - 96             ; 8 bytes
    %define wc.hbrBackground   RBP - 88             ; 8 bytes
    %define wc.lpszMenuName    RBP - 80             ; 8 bytes
    %define wc.lpszClassName   RBP - 72             ; 8 bytes
    %define wc.hIconSm         RBP - 64             ; 8 bytes. End on an 8 byte boundary
    
    ; msg结构最大成员8字节 总字节数44+4字节的结构对齐=48 48/8=6 
    %define msg                RBP - 56             ; MSG structure, 48 bytes
    %define msg.hwnd           RBP - 56             ; 8 bytes. Start on an 8 byte boundary
    %define msg.message        RBP - 48             ; 4 bytes
    %define msg.Padding1       RBP - 44             ; 4字节自然对齐
    %define msg.wParam         RBP - 40             ; 8 bytes
    %define msg.lParam         RBP - 32             ; 8 bytes
    %define msg.time           RBP - 24             ; 4 bytes
    %define msg.py.x           RBP - 20             ; 4 bytes
    %define msg.pt.y           RBP - 16             ; 4 bytes
    %define msg.Padding2       RBP - 12             ; 4字节结构对齐
    
    %define hWnd               RBP - 8              ; 8 bytes
    
     mov   dword [wc.cbSize], 80                    ; [RBP - 136]
     mov   dword [wc.style], CS_HREDRAW | CS_VREDRAW | CS_BYTEALIGNWINDOW  ; [RBP - 132]
     lea   RAX, [REL WndProc]
     mov   qword [wc.lpfnWndProc], RAX              ; [RBP - 128]
     mov   dword [wc.cbClsExtra], NULL              ; [RBP - 120]
     mov   dword [wc.cbWndExtra], NULL              ; [RBP - 116]
     mov   RAX, qword [REL hInstance]               ; Global
     mov   qword [wc.hInstance], RAX                ; [RBP - 112]
    
     sub   RSP, 32 + 16                             ; Shadow space + 2 parameters
     xor   ECX, ECX
     mov   EDX, IDI_APPLICATION
     mov   R8D, IMAGE_ICON
     xor   R9D, R9D
     mov   qword [RSP + 4 * 8], NULL
     mov   qword [RSP + 5 * 8], LR_SHARED
     call  LoadImageA                               ; Large program icon
     mov   qword [wc.hIcon], RAX                    ; [RBP - 104]
     add   RSP, 48                                  ; Remove the 48 bytes
    
     sub   RSP, 32 + 16                             ; Shadow space + 2 parameters
     xor   ECX, ECX
     mov   EDX, IDC_ARROW
     mov   R8D, IMAGE_CURSOR
     xor   R9D, R9D
     mov   qword [RSP + 4 * 8], NULL
     mov   qword [RSP + 5 * 8], LR_SHARED
     call  LoadImageA                               ; Cursor
     mov   qword [wc.hCursor], RAX                  ; [RBP - 96]
     add   RSP, 48                                  ; Remove the 48 bytes
    
     mov   qword [wc.hbrBackground], COLOR_WINDOW + 1  ; [RBP - 88]
     mov   qword [wc.lpszMenuName], NULL            ; [RBP - 80]
     lea   RAX, [REL ClassName]
     mov   qword [wc.lpszClassName], RAX            ; [RBP - 72]
    
     sub   RSP, 32 + 16                             ; Shadow space + 2 parameters
     xor   ECX, ECX
     mov   EDX, IDI_APPLICATION
     mov   R8D, IMAGE_ICON
     xor   R9D, R9D
     mov   qword [RSP + 4 * 8], NULL
     mov   qword [RSP + 5 * 8], LR_SHARED
     call  LoadImageA                               ; Small program icon
     mov   qword [wc.hIconSm], RAX                  ; [RBP - 64]
     add   RSP, 48                                  ; Remove the 48 bytes
    
     sub   RSP, 32                                  ; 32 bytes of shadow space
     lea   RCX, [wc]                                ; [RBP - 136]
     call  RegisterClassExA
     add   RSP, 32                                  ; Remove the 32 bytes
    
     sub   RSP, 32 + 64                             ; Shadow space + 8 parameters
     mov   ECX, WS_EX_COMPOSITED
     lea   RDX, [REL ClassName]                     ; Global
     lea   R8, [REL WindowName]                     ; Global
     mov   R9D, WS_OVERLAPPEDWINDOW
     mov   dword [RSP + 4 * 8], CW_USEDEFAULT
     mov   dword [RSP + 5 * 8], CW_USEDEFAULT
     mov   dword [RSP + 6 * 8], WindowWidth
     mov   dword [RSP + 7 * 8], WindowHeight
     mov   qword [RSP + 8 * 8], NULL
     mov   qword [RSP + 9 * 8], NULL
     mov   RAX, qword [REL hInstance]               ; Global
     mov   qword [RSP + 10 * 8], RAX
     mov   qword [RSP + 11 * 8], NULL
     call  CreateWindowExA
     mov   qword [hWnd], RAX                        ; [RBP - 8]
     add   RSP, 96                                  ; Remove the 96 bytes
    
     sub   RSP, 32                                  ; 32 bytes of shadow space
     mov   RCX, qword [hWnd]                        ; [RBP - 8]
     mov   EDX, SW_SHOWNORMAL
     call  ShowWindow
     add   RSP, 32                                  ; Remove the 32 bytes
    
     sub   RSP, 32                                  ; 32 bytes of shadow space
     mov   RCX, qword [hWnd]                        ; [RBP - 8]
     call  UpdateWindow
     add   RSP, 32                                  ; Remove the 32 bytes
    
    .MessageLoop:
     sub   RSP, 32                                  ; 32 bytes of shadow space
     lea   RCX, [msg]                               ; [RBP - 56]
     xor   EDX, EDX
     xor   R8D, R8D
     xor   R9D, R9D
     call  GetMessageA
     add   RSP, 32                                  ; Remove the 32 bytes
     cmp   RAX, 0
     je    .Done
    
     sub   RSP, 32                                  ; 32 bytes of shadow space
     mov   RCX, qword [hWnd]                        ; [RBP - 8]
     lea   RDX, [msg]                               ; [RBP - 56]
     call  IsDialogMessageA                         ; For keyboard strokes
     add   RSP, 32                                  ; Remove the 32 bytes
     cmp   RAX, 0
     jne   .MessageLoop                             ; Skip TranslateMessage and DispatchMessageA
    
     sub   RSP, 32                                  ; 32 bytes of shadow space
     lea   RCX, [msg]                               ; [RBP - 56]
     call  TranslateMessage
     add   RSP, 32                                  ; Remove the 32 bytes
    
     sub   RSP, 32                                  ; 32 bytes of shadow space
     lea   RCX, [msg]                               ; [RBP - 56]
     call  DispatchMessageA
     add   RSP, 32                                  ; Remove the 32 bytes
     jmp   .MessageLoop
    
    .Done:
     mov   RSP, RBP                                 ; Remove the stack frame
     pop   RBP
     xor   EAX, EAX
     ret
    
    ; 回调函数
    WndProc:
     push  RBP                                      ; Set up a stack frame
     mov   RBP, RSP
    
    ; 获取阴影空间
    ; call+上面的push  RBP会导致rsp-16,所以第一个要+16
    %define hWnd   RBP + 16                         ; Location of the shadow space setup by
    %define uMsg   RBP + 24                         ; the calling function
    %define wParam RBP + 32
    %define lParam RBP + 40
    
    ; 将函数参数放在阴影空间
     mov   qword [hWnd], RCX                        ; Free up RCX RDX R8 R9 by spilling the
     mov   qword [uMsg], RDX                        ; 4 passed parameters to the shadow space
     mov   qword [wParam], R8                       ; We can now access these parameters by name
     mov   qword [lParam], R9
    
     cmp   qword [uMsg], WM_DESTROY                 ; [RBP + 24]
     je    _WMDESTROY
    
    _DefaultMessage:
     ; DefWindowProcA需要4个参数,4*8=32 32/16=2 能对齐不用手动对齐
     sub   RSP, 32                                  ; 32 bytes of shadow space
     mov   RCX, qword [hWnd]                        ; [RBP + 16]
     mov   RDX, qword [uMsg]                        ; [RBP + 24]
     mov   R8, qword [wParam]                       ; [RBP + 32]
     mov   R9, qword [lParam]                       ; [RBP + 40]
     call  DefWindowProcA
     add   RSP, 32                                  ; Remove the 32 bytes
    
     mov   RSP, RBP                                 ; Remove the stack frame
     pop   RBP
     ret
    
    _WMDESTROY:
     sub   RSP, 32                                  ; 32 bytes of shadow space
     xor   ECX, ECX
     call  PostQuitMessage
     add   RSP, 32                                  ; Remove the 32 bytes
    
     xor   EAX, EAX                                 ; WM_DESTROY has been processed, return 0
     mov   RSP, RBP                                 ; Remove the stack frame
     pop   RBP
     ret
    

    x86 基本窗口扩展 看原文

    对基本窗口示例的改进:

    • 窗口将在屏幕上居中
    • 客户区现在将是正确的大小(在调整大小之前)
    • 窗口具有背景色
    • 将创建2个静态控件。单击时文本会更改颜色
    • 创建2个编辑控件。Tab键可用于更改焦点
    • 静态和编辑控件的字体从系统默认值更改
    • 窗口上有一个黑色矩形
    • 关闭窗口时显示退出确认

    x64 基本窗口扩展 看原文

    对基本窗口示例的改进:

    • 窗口将在屏幕上居中
    • 客户区现在将是正确的大小(在调整大小之前)
    • 窗口具有背景色
    • 将创建2个静态控件。单击时文本会更改颜色
    • 创建2个编辑控件。Tab键可用于更改焦点
    • 静态和编辑控件的字体从系统默认值更改
    • 窗口上有一个黑色矩形
    • 关闭窗口时显示退出确认
  • 相关阅读:
    简单说说Restful API
    事务的ACID特性
    WPF DataGrid与ListView性能对比与场景选择
    WPF MVVM实现INotifyPropertyChanged数据监听
    学习Promise异步编程
    CSS单位
    Mac Docker设置国内镜像加速器
    Mac下安装Redis,附可视化工具Medis
    预告 | XPocket开源产品发布会将于1月15日正式线上直播!
    CSDN资源免费下载
  • 原文地址:https://www.cnblogs.com/ajanuw/p/13220066.html
Copyright © 2011-2022 走看看