当前位置: 首页 > news >正文

nasm - BasicWindowExt_32

文章目录

    • nasm - BasicWindowExt_32
    • 概述
    • 笔记
    • nasm_main.asm
    • my_build.bat
    • END

nasm - BasicWindowExt_32

概述

学习找到的demo

笔记

nasm_main.asm

; @file nasm_main.asm
; @brief 用NASM实现一个32bits的扩展窗口
; nasm - BasicWindowExt_32
; 用NASM做的程序,EXE体积真小啊. 
; 同样的功能用VS2019 c++来做,即使在release版下调整编译设置, 也做不到这么小的EXE体积。
; 就是用NASM写程序会很麻烦, 不是有刚需,还是用VS2019来写。不过可以考虑用NASM写一部分代码, 编译成obj后,作为外部函数, link到VS2019的工程中.

; ----------------------------------------
; 宏定义
; ----------------------------------------
; Basic Window Extended, 32 bit. V1.04
ANSI_CHARSET         EQU 0                      ; Constants
BLACKNESS            EQU 42h
CLIP_DEFAULT_PRECIS  EQU 0
CS_BYTEALIGNWINDOW   EQU 2000h
CS_HREDRAW           EQU 2
CS_VREDRAW           EQU 1
DEFAULT_PITCH        EQU 0
ES_AUTOHSCROLL       EQU 80h
ES_CENTER            EQU 1
FALSE                EQU 0
GRAY_BRUSH           EQU 2
IDC_ARROW            EQU 7F00h
IDI_APPLICATION      EQU 7F00h
IDNO                 EQU 7
IMAGE_CURSOR         EQU 2
IMAGE_ICON           EQU 1
LR_SHARED            EQU 8000h
MB_DEFBUTTON2        EQU 100h
MB_YESNO             EQU 4
NULL                 EQU 0
NULL_BRUSH           EQU 5
OPAQUE               EQU 2
PROOF_QUALITY        EQU 2
SM_CXFULLSCREEN      EQU 10h
SM_CYFULLSCREEN      EQU 11h
SS_CENTER            EQU 1
SS_NOTIFY            EQU 100h
SW_SHOWNORMAL        EQU 1
TRUE                 EQU 1
WM_CLOSE             EQU 10h
WM_COMMAND           EQU 111h
WM_CREATE            EQU 1
WM_CTLCOLOREDIT      EQU 133h
WM_CTLCOLORSTATIC    EQU 138h
WM_DESTROY           EQU 2
WM_PAINT             EQU 0Fh
WM_SETFONT           EQU 30h
OUT_DEFAULT_PRECIS   EQU 0
WS_CHILD             EQU 40000000h
WS_EX_COMPOSITED     EQU 2000000h
WS_OVERLAPPEDWINDOW  EQU 0CF0000h
WS_TABSTOP           EQU 10000h
WS_VISIBLE           EQU 10000000h

WindowWidth          EQU 640
WindowHeight         EQU 170
Static1ID            EQU 100
Static2ID            EQU 101
Edit1ID              EQU 102
Edit2ID              EQU 103

; ----------------------------------------
; 外部函数声明
; ----------------------------------------
extern AdjustWindowRectEx                   ; Import external symbols
extern BeginPaint                            ; Windows API functions, decorated
extern BitBlt
extern CreateFontA
extern CreateSolidBrush
extern CreateWindowExA
extern DefWindowProcA
extern DeleteObject
extern DestroyWindow
extern DispatchMessageA
extern EndPaint
extern ExitProcess
extern GetDlgCtrlID
extern GetMessageA
extern GetModuleHandleA
extern GetStockObject
extern GetSystemMetrics
extern InvalidateRect
extern IsDialogMessageA
extern LoadImageA
extern MessageBoxA
extern PostQuitMessage
extern RegisterClassExA
extern SendMessageA
extern SetBkColor
extern SetBkMode
extern SetTextColor
extern ShowWindow
extern TranslateMessage
extern UpdateWindow

global Start                                    ; Export symbols. The entry point

; ----------------------------------------
; 区段定义
; ----------------------------------------
section .data                                   ; Initialized data segment
 Static1Colour    dd 0F0F0F0h                   ; Colour (0BBGGRRh)
 Static1ColourA   dd 020A0F0h
 Static2Colour    dd 000FFFFh
 Static2ColourA   dd 08000FFh
 Edit1TextColour  dd 0F590F5h
 Edit1BackColour  dd 0A00000h
 Edit2TextColour  dd 0A56E3Bh
 Edit2BackColour  dd 0FEFE8Eh
 BackgroundColour dd 0A56E3Bh   
 WindowName       db "Basic Window Extended 32", 0
 ClassName        db "Window", 0
 SegoeUI          db "Segoe UI", 0
 StaticClass      db "STATIC", 0
 EditClass        db "EDIT", 0
 Text1            db "ABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789", 0
 Text2            db "abcdefghijklmnopqrstuvwxyz_0123456789", 0
 ExitText         db "Do you want to exit?", 0

section .bss                                    ; Uninitialized data segment
 hInstance        resd 1
 BackgroundBrush  resd 1
 Font             resd 1
 Static1          resd 1
 Static2          resd 1
 Edit1            resd 1
 Edit2            resd 1

section .text                                   ; Code segment
; ----------------------------------------
; 函数定义
; ----------------------------------------
; fn_x 是顶层函数, 有栈平衡的操作, 可以 call
; proc.x 是顶层函数调用的功能实现(逻辑实现, 功能块), 没有栈平衡的操作, 不能直接call, 只能 je, jmp
fn_Start:
 push  NULL
 call  GetModuleHandleA
 mov   dword [hInstance], EAX

 call  fn_WinMain

; .Exit:
 push  NULL
 call  ExitProcess
; ----------------------------------------
fn_WinMain:
 push  EBP                                      ; Set up a stack frame
 mov   EBP, ESP
 sub   ESP, 104                                 ; 104 bytes for local variables

%define Screen.Width       EBP - 104
%define Screen.Height      EBP - 100

%define ClientArea         EBP - 96             ; RECT structure. 16 bytes
%define ClientArea.left    EBP - 96
%define ClientArea.top     EBP - 92
%define ClientArea.right   EBP - 88
%define ClientArea.bottom  EBP - 84

%define wc                 EBP - 80             ; WNDCLASSEX structure. 48 bytes
%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 structure. 28 bytes
%define msg.hwnd           EBP - 32             ; Breaking out each member is not necessary
%define msg.message        EBP - 28             ; in this case, but it shows where each
%define msg.wParam         EBP - 24             ; member is on the stack
%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

 push  dword [BackgroundColour]
 call  CreateSolidBrush                      ; Create a brush for the window backgound
 mov   dword [BackgroundBrush], EAX

 mov   dword [wc.cbSize], 48                    ; [EBP - 80]
 mov   dword [wc.style], CS_HREDRAW | CS_VREDRAW | CS_BYTEALIGNWINDOW  ; [EBP - 76]
 mov   dword [wc.lpfnWndProc], fn_WndProc          ; [EBP - 72]
 mov   dword [wc.cbClsExtra], NULL              ; [EBP - 68]
 mov   dword [wc.cbWndExtra], NULL              ; [EBP - 64]
 mov   EAX, dword [hInstance]
 mov   dword [wc.hInstance], EAX                ; [EBP - 60]

 push  LR_SHARED
 push  NULL
 push  NULL
 push  IMAGE_ICON
 push  IDI_APPLICATION
 push  NULL
 call  LoadImageA                           ; Large program icon
 mov   dword [wc.hIcon], EAX                    ; [EBP - 56]
 ; // x86程序调用WinApi后,不用自己进行栈平衡。被调用者自己做了栈平衡

 push  LR_SHARED
 push  NULL
 push  NULL
 push  IMAGE_CURSOR
 push  IDC_ARROW
 push  NULL
 call  LoadImageA                           ; Cursor
 mov   dword [wc.hCursor], EAX                  ; [EBP - 52]

 mov   EAX, dword [BackgroundBrush]
 mov   dword [wc.hbrBackground], EAX            ; [EBP - 48]
 mov   dword [wc.lpszMenuName], NULL            ; [EBP - 44]
 mov   dword [wc.lpszClassName], ClassName      ; [EBP - 40]

 push  LR_SHARED
 push  NULL
 push  NULL
 push  IMAGE_ICON
 push  IDI_APPLICATION
 push  NULL
 call  LoadImageA                           ; Small program icon
 mov   dword [wc.hIconSm], EAX                  ; [EBP - 36]

 lea   EAX, [wc]                                ; [EBP - 80]
 push  EAX
 call  RegisterClassExA

 push  SM_CXFULLSCREEN
 call  GetSystemMetrics                      ; Get the current screen width
 mov   dword [Screen.Width], EAX                ; [EBP - 104]

 push  SM_CYFULLSCREEN
 call  GetSystemMetrics                      ; Get the current screen height
 mov   dword [Screen.Height], EAX               ; [EBP - 100]

 mov   dword [ClientArea.left], 0               ; [EBP - 96]
 mov   dword [ClientArea.top], 0                ; [EBP - 92]
 mov   dword [ClientArea.right], WindowWidth    ; [EBP - 88]
 mov   dword [ClientArea.bottom], WindowHeight  ; [EBP - 84]

 push  WS_EX_COMPOSITED                         ; Extended style
 push  NULL
 push  WS_OVERLAPPEDWINDOW                      ; Style
 lea   EAX, [ClientArea]                        ; [EBP - 96]
 push  EAX
 call  AdjustWindowRectEx                   ; Get window size for the desired client size
                                                ; Size is returned in ClientArea
 mov   EAX, dword [ClientArea.top]              ; [EBP - 92]
 sub   dword [ClientArea.bottom], EAX           ; New Height = ClientArea.bottom - ClientArea.top

 mov   EAX, dword [ClientArea.left]             ; [EBP - 96]
 sub   dword [ClientArea.right], EAX            ; New Width = ClientArea.right - ClientArea.left

 push  NULL
 push  dword [hInstance]
 push  NULL
 push  NULL

 push  dword [ClientArea.bottom]                ; Height. [EBP - 84]
 push  dword [ClientArea.right]                 ; Width. [EBP - 88]

 xor   ECX, ECX
 mov   EAX, dword [Screen.Height]               ; [EBP - 100]
 sub   EAX, dword [ClientArea.bottom]           ; Corrected window height. [EBP - 84]
 cmovs EAX, ECX                                 ; Clamp to 0 (top) if negative
 shr   EAX, 1                                   ; EAX = (Screen.Height - window height) / 2
 push  EAX                                      ; Y position, now centred

 mov   EAX, dword [Screen.Width]                ; [EBP - 104]
 sub   EAX, dword [ClientArea.right]            ; Corrected window width. [EBP - 88]
 cmovs EAX, ECX                                 ; Clamp to 0 (left) if negative
 shr   EAX, 1                                   ; EAX = (Screen.Width - window width) / 2
 push  EAX                                      ; X position, now centred

 push  WS_OVERLAPPEDWINDOW
 push  WindowName
 push  ClassName
 push  WS_EX_COMPOSITED
 call  CreateWindowExA
 mov   dword [hWnd], EAX                        ; [EBP - 4]

 push  SW_SHOWNORMAL
 push  dword [hWnd]                             ; [EBP - 4]
 call  ShowWindow

 push  dword [hWnd]                             ; [EBP - 4]
 call  UpdateWindow

.MessageLoop:
 push  NULL
 push  NULL
 push  NULL
 lea   EAX, [msg]                               ; [EBP - 32]
 push  EAX
 call  GetMessageA
 cmp   EAX, 0
 je    .Done

 lea   EAX, [msg]                               ; [EBP - 32]
 push  EAX
 push  dword [hWnd]                             ; [EBP - 4]
 call  IsDialogMessageA                      ; For keyboard strokes
 cmp   EAX, 0
 jne   .MessageLoop                             ; Skip TranslateMessage and DispatchMessage

 lea   EAX, [msg]                               ; [EBP - 32]
 push  EAX
 call  TranslateMessage

 lea   EAX, [msg]                               ; [EBP - 32]
 push  EAX
 call  DispatchMessageA
 jmp   .MessageLoop

.Done:
 xor   EAX, EAX
 mov   ESP, EBP                                 ; Remove the stack frame
 pop   EBP
 ret
; ----------------------------------------
fn_WndProc:
 push  EBP                                      ; Set up a stack frame
 mov   EBP, ESP
 sub   ESP, 68                                  ; 68 bytes for local variables

%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

%define ps                  EBP - 68            ; PAINTSTRUCT structure. 64 bytes
%define ps.hdc              EBP - 68
%define ps.fErase           EBP - 64
%define ps.rcPaint.left     EBP - 60
%define ps.rcPaint.top      EBP - 56
%define ps.rcPaint.right    EBP - 52
%define ps.rcPaint.bottom   EBP - 48
%define ps.Restore          EBP - 44
%define ps.fIncUpdate       EBP - 40
%define ps.rgbReserved      EBP - 36

%define hdc                 EBP - 4

 cmp   dword [uMsg], WM_CLOSE                   ; [EBP + 12]
 je    .LB_WMCLOSE

 cmp   dword [uMsg], WM_COMMAND                 ; [EBP + 12]
 je    proc.LB_WMCOMMAND

 cmp   dword [uMsg], WM_CREATE                  ; [EBP + 12]
 je    proc.LB_WMCREATE

 cmp   dword [uMsg], WM_CTLCOLOREDIT            ; [EBP + 12]
 je    proc.LB_WMCTLCOLOREDIT

 cmp   dword [uMsg], WM_CTLCOLORSTATIC          ; [EBP + 12]
 je    proc.LB_WMCTLCOLORSTATIC

 cmp   dword [uMsg], WM_DESTROY                 ; [EBP + 12]
 je    proc.LB_WMDESTROY

 cmp   dword [uMsg], WM_PAINT                   ; [EBP + 12]
 je    proc.LB_WMPAINT

.LB_DefaultMessage:
 push  dword [lParam]                           ; [EBP + 20]
 push  dword [wParam]                           ; [EBP + 16]
 push  dword [uMsg]                             ; [EBP + 12]
 push  dword [hWnd]                             ; [EBP + 8]
 call  DefWindowProcA
 jmp   LB_Return

.LB_WMCLOSE:
 push  MB_YESNO | MB_DEFBUTTON2
 push  WindowName
 push  ExitText
 push  dword [hWnd]                             ; [EBP + 8]
 call  MessageBoxA

 cmp   EAX, IDNO
 ; // 如果要跳到的目标标签已经越过了最近的一个外部标签, 那么这个目标标签就应该是外部标签 x
 ; // 如果要跳到的目标标签没到达最近的一个外部标签, 那么这个目标标签就是内部标签 .x
 je    LB_Return.WM_Processed

 push  dword [hWnd]                             ; [EBP + 8]
 call  DestroyWindow                         ; Send a WM_DESTROY message
 jmp   LB_Return.WM_Processed

proc.LB_WMCOMMAND:
 mov   EAX, dword [wParam]                      ; EAX = ID. [EBP + 16]

 cmp   AX, Static1ID
 je    .Static1

 cmp   AX, Static2ID
 je    .Static2

 jmp   LB_Return.WM_Processed

.Static1:
 mov   EAX, dword [Static1Colour]
 mov   EBX, dword [Static1ColourA]
 mov   dword [Static1Colour], EBX
 mov   dword [Static1ColourA], EAX              ; Swap colours

 push  TRUE
 push  NULL
 push  dword [lParam]                           ; Static1 handle. [EBP + 20]
 call  InvalidateRect                       ; Redraw control
 jmp   LB_Return.WM_Processed

.Static2:
 mov   EAX, dword [Static2Colour]
 mov   EBX, dword [Static2ColourA]
 mov   dword [Static2Colour], EBX
 mov   dword [Static2ColourA], EAX              ; Swap colours

 push  TRUE
 push  NULL
 push  dword [lParam]                           ; Static2 handle. [EBP + 20]
 call  InvalidateRect                       ; Redraw control
 jmp   LB_Return.WM_Processed

proc.LB_WMCREATE:
 push  NULL
 push  dword [hInstance]
 push  Static1ID
 push  dword [hWnd]                             ; [EBP + 8]
 push  20                                       ; Height
 push  400                                      ; Width
 push  10                                       ; Y
 push  120                                      ; X
 push  WS_CHILD | WS_VISIBLE | SS_NOTIFY | SS_CENTER
 push  Text1                                    ; Default text
 push  StaticClass
 push  NULL
 call  CreateWindowExA
 mov   dword [Static1], EAX

 push  NULL
 push  dword [hInstance]
 push  Static2ID
 push  dword [hWnd]                             ; [EBP + 8]
 push  20                                       ; Height
 push  400                                      ; Width
 push  40                                       ; Y
 push  120                                      ; X
 push  WS_CHILD | WS_VISIBLE | SS_NOTIFY | SS_CENTER
 push  Text2                                    ; Default text
 push  StaticClass
 push  NULL
 call  CreateWindowExA
 mov   dword [Static2], EAX

 push  NULL
 push  dword [hInstance]
 push  Edit1ID
 push  dword [hWnd]                             ; [EBP + 8]
 push  20                                       ; Height
 push  400                                      ; Width
 push  70                                       ; Y
 push  120                                      ; X
 push  WS_CHILD | WS_VISIBLE | ES_CENTER | WS_TABSTOP | ES_AUTOHSCROLL
 push  Text1                                    ; Default text
 push  EditClass
 push  NULL
 call  CreateWindowExA
 mov   dword [Edit1], EAX

 push  NULL
 push  dword [hInstance]
 push  Edit2ID
 push  dword [hWnd]                             ; [EBP + 8]
 push  20                                       ; Height
 push  400                                      ; Width
 push  100                                      ; Y
 push  120                                      ; X
 push  WS_CHILD | WS_VISIBLE | ES_CENTER | WS_TABSTOP | ES_AUTOHSCROLL
 push  Text2                                    ; Default text
 push  EditClass
 push  NULL
 call  CreateWindowExA
 mov   dword [Edit2], EAX

 lea   EAX, [SegoeUI]
 push  EAX
 push  DEFAULT_PITCH
 push  PROOF_QUALITY
 push  CLIP_DEFAULT_PRECIS
 push  OUT_DEFAULT_PRECIS
 push  ANSI_CHARSET
 push  NULL
 push  NULL
 push  NULL
 push  400                                      ; Weight
 push  NULL
 push  NULL
 push  NULL
 push  20                                       ; Size
 call  CreateFontA
 mov   dword [Font], EAX

 push  FALSE
 push  dword [Font]
 push  WM_SETFONT
 push  dword [Static1]
 call  SendMessageA                         ; Set Static1 font

 push  FALSE
 push  dword [Font]
 push  WM_SETFONT
 push  dword [Static2]
 call  SendMessageA                         ; Set Static2 font

 push  FALSE
 push  dword [Font]
 push  WM_SETFONT
 push  dword [Edit1]
 call  SendMessageA                         ; Set Edit1 font

 push  FALSE
 push  dword [Font]
 push  WM_SETFONT
 push  dword [Edit2]
 call  SendMessageA                         ; Set Edit2 font

 jmp   LB_Return.WM_Processed

proc.LB_WMCTLCOLOREDIT:                                 ; For colouring edit controls
 push  dword [lParam]                           ; [EBP + 20]
 call  GetDlgCtrlID                          ; EAX = ID

 cmp   EAX, Edit1ID
 je    .Edit1

 cmp   EAX, Edit2ID
 je    .Edit2

; .Default:
 push  NULL_BRUSH
 call  GetStockObject                        ; Return a brush
 jmp   LB_Return

.Edit1:
 push  dword [Edit1TextColour]
 push  dword [wParam]                           ; [EBP + 16]
 call  SetTextColor

 push  OPAQUE
 push  dword [wParam]                           ; [EBP + 16]
 call  SetBkMode

 push  dword [Edit1BackColour]
 push  dword [wParam]                           ; [EBP + 16]
 call  SetBkColor

 push  NULL_BRUSH
 call  GetStockObject                        ; Return a brush
 jmp   LB_Return

.Edit2:
 push  dword [Edit2TextColour]
 push  dword [wParam]                           ; [EBP + 16]
 call  SetTextColor

 push  OPAQUE
 push  dword [wParam]                           ; [EBP + 16]
 call  SetBkMode

 push  dword [Edit2BackColour]
 push  dword [wParam]                           ; [EBP + 16]
 call  SetBkColor

 push  NULL_BRUSH
 call  GetStockObject                        ; Return a brush
 jmp   LB_Return

proc.LB_WMCTLCOLORSTATIC:                               ; For colouring static controls
 push  dword [lParam]                           ; [EBP + 20]
 call  GetDlgCtrlID                          ; EAX = ID

 cmp   EAX, Static1ID
 je    .Static1

 cmp   EAX, Static2ID
 je    .Static2

; .x 作为子标签 隶属于上面的一个标签或函数, 其他标签和函数也可以有同样名字的.x 不冲突
; .Default:
 push  NULL_BRUSH
 call  GetStockObject                        ; Return a brush
 jmp   LB_Return

.Static1:
 push  dword [Static1Colour]
 push  dword [wParam]                           ; [EBP + 16]
 call  SetTextColor

 push  OPAQUE
 push  dword [wParam]                           ; [EBP + 16]
 call  SetBkMode

 push  0604060h
 push  dword [wParam]                           ; [EBP + 16]
 call  SetBkColor

 push  NULL_BRUSH
 call  GetStockObject                        ; Return a brush
 jmp   LB_Return

.Static2:
 push  dword [Static2Colour]
 push  dword [wParam]                           ; [EBP + 16]
 call  SetTextColor

 push  OPAQUE
 push  dword [wParam]                           ; [EBP + 16]
 call  SetBkMode

 push  0005000h
 push  dword [wParam]                           ; [EBP + 16]
 call  SetBkColor

 push  GRAY_BRUSH
 call  GetStockObject                        ; Return a brush
 jmp   LB_Return

proc.LB_WMDESTROY:
 push  dword [BackgroundBrush]
 call  DeleteObject

 push  dword [Font]
 call  DeleteObject

 push  NULL
 call  PostQuitMessage
 jmp   LB_Return.WM_Processed

proc.LB_WMPAINT:
 lea   EAX, [ps]                                ; Starting address of PAINTSTRUCT. [EBP - 68]
 push  EAX
 push  dword [hWnd]                             ; [EBP + 8]
 call  BeginPaint
 mov   dword [hdc], EAX

 push  BLACKNESS                                ; Operation
 push  0                                        ; Source Y
 push  0                                        ; Source X
 push  dword [hdc]                              ; Source device context
 push  20                                       ; Height
 push  400                                      ; Width
 push  130                                      ; Destination Y
 push  120                                      ; Destination X
 push  dword [hdc]                              ; Destination device context
 call  BitBlt                               ; Blit a black rectangle

 lea   EAX, [ps]                                ; [EBP - 68]
 push  EAX
 push  dword [hWnd]                             ; [EBP + 8]
 call  EndPaint

LB_Return.WM_Processed:
 xor   EAX, EAX                                 ; WM_ has been processed, return 0

LB_Return:
 mov   ESP, EBP                                 ; Remove the stack frame
 pop   EBP
 ret   16                                       ; Pop 4 parameters off the stack and return
; ----------------------------------------

my_build.bat

@echo off
cls

rem ----------------------------------------
rem my_build.bat

rem env
rem NASM version 2.16.03 compiled on Apr 17 2024
rem GoLink.Exe Version 1.0.4.6  Copyright Jeremy Gordon 2002-2025

set path=C:\Program Files\NASM;C:\soft\Golink;%path%

rem . bat默认是不支持中文的 .
rem echo full path name - %~f0
rem echo full path      - %~dp0
rem echo file name      - %~nx0
rem echo work path      - %cd%
rem all param           - %*

rem . rem注释的第1个字符和最后1个字符,不能是中文,否则有概率会当作命令来执行 .
rem . 调试.bat的方法 .
rem . 如果.bat写的不对,又不容易看出来,只能在每行后面加pause, 然后执行.bat, 然后按一下空格执行一行 .

set prj_src_name_1=nasm_main.asm
set prj_obj_name_1=nasm_main.obj
set prj_exe_name=BasicWindowExt_32.exe

rem win32 or win64
set prj_build_type=win32

rem /console or /SUBSYSTEM:WINDOWS
set prj_sub_sys=/SUBSYSTEM:WINDOWS

echo [%~nx0 %*]

if "%1" == "build" (
    call :fn_build
) else if "%1" == "clear" (
    call :fn_clear
) else (
    call :fn_usage
)

goto end

rem ----------------------------------------
rem function
rem ----------------------------------------

:fn_usage
echo usage my_build.bat [option]
echo build - build asm to EXE
echo clear - clear trush on the project
exit /b

rem ----------------------------------------
:fn_build
echo build ...

rem find file on work path
call :fn_del_file "%prj_obj_name_1%"

nasm -f %prj_build_type% %prj_src_name_1% -o %prj_obj_name_1%
rem 用IDA打开.obj 已经可以看到实现逻辑了

call :fn_del_file "%prj_exe_name%"

rem 如果不指定要连接的dll, 会报错
golink /entry:fn_Start '%prj_sub_sys%' kernel32.dll user32.dll gdi32.dll %prj_obj_name_1% /fo %prj_exe_name%

call :fn_exec "%prj_exe_name%"
exit /b

rem ----------------------------------------
:fn_clear
echo clear ...
call :fn_del_file "%prj_obj_name_1%"
call :fn_del_file "%prj_exe_name%"
exit /b

rem ----------------------------------------
:fn_del_file
if exist "%~1"  (
    echo del "%~1" 
    del "%~1" 
)
exit /b

:fn_exec
if exist "%~1"  (
    echo exec "%~1"
    %~1
)
exit /b

rem ----------------------------------------
:end
echo END
rem pause
call cmd

END

相关文章:

  • 当电脑上有几个python版本Vscode选择特定版本python
  • C++ 标准库——函数对象和函数适配器
  • linux文件管理命令ln
  • 算法菜鸡备战3月2日传智杯省赛----0221
  • 大数据组件(四)快速入门实时数据湖存储系统Apache Paimon(3)
  • 《代码随想录第三十九天》——背包问题二维、背包问题一维、分割等和子集
  • 【进程与线程】Linux 线程、同步以及互斥
  • 学习整理安装php的uuid扩展以及uuid调用方法
  • vue2.x中父组件通过props向子组件传递数据详细解读
  • logstash中的input插件(http插件,graphite插件)
  • python杂学
  • 视觉应用工程师(面试)
  • OpenBMC:BmcWeb实例化App
  • 非常简洁的一个 Excel 导出封装,生成多个 Excel 文件并打包成 zip 通过浏览器下载
  • python小项目编程-中级(1、图像处理)
  • 【蓝桥杯集训·每日一题2025】 AcWing 6118. 蛋糕游戏 python
  • 欧洲跨境组网专线:企业出海的高效网络解决方案
  • Python(二十二)实现各大跨境船公司物流查询CMA船司物流查询
  • DeepSeek技术演进史:从MoE到当前架构
  • npm/pnpm软链接
  • 铜仁 网站开发/关键词调词平台
  • 网站建设自学/竞价账户托管哪家好
  • 陇南网站设计/seo长尾快速排名
  • 网站 备案 拍照/搜索引擎营销的五大特点
  • 哪些网站做企业招聘不要花钱/方象科技专注于什么领域
  • 网站制作./关键词优化策略