macro.asm

本文介绍了一组用于MASM32的宏指令,包括加载库和获取过程地址、初始化全局变量、字符串操作等功能。这些宏简化了汇编语言编程中的常见任务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自行将下面的代码保存为“macro.asm”即可。亲测CTXT("Hi. i'm Sollyu.")通过!
; ###########################################################################
;
;                         Support macros for MASM32
;
; ###########################################################################

    ; ----------------------------------------------------------
    ; load a library and get the procedure address in one macro
    ; return value for the proc address in in EAX
    ; ----------------------------------------------------------
      LoadProcAddress MACRO quoted_text1,quoted_text2
        LOCAL library_name
        LOCAL proc_name
          .data
            library_name db quoted_text1,0
            proc_name db quoted_text2,0
          .code
        invoke LoadLibrary,ADDR library_name
        invoke GetProcAddress,eax,ADDR proc_name
      ENDM

    ; -------------------------
    ; initialised GLOBAL value
    ; -------------------------
      GLOBAL MACRO variable:VARARG
      .data
        variable
      .code
      ENDM

    ; --------------------------------
    ; initialised GLOBAL string value
    ; --------------------------------
      STRING MACRO variable:REQ,args:VARARG
      .data
        variable db args,0
      .code
      ENDM

    ; ---------------------
    ; literal string MACRO
    ; ---------------------
      literal MACRO quoted_text:VARARG
        LOCAL local_text
        .data
          local_text db quoted_text,0
        .code
        EXITM <local_text>
      ENDM
    ; --------------------------------
    ; string address in INVOKE format
    ; --------------------------------
      SADD MACRO quoted_text:VARARG
        EXITM <ADDR literal(quoted_text)>
      ENDM
    ; --------------------------------
    ; string OFFSET for manual coding
    ; --------------------------------
      CTXT MACRO quoted_text:VARARG
        EXITM <offset literal(quoted_text)>
      ENDM

    ; --------------------------------------------------
    ; Two macros for allocating and freeing OLE memory.
    ; stralloc returns the handle/address of the string
    ; memory in eax. strfree uses the handle to free
    ; memory after use.
    ; NOTE that you must use the following INCLUDE &
    ; LIB files with these two macros.
    ;
    ;       include \MASM32\include\oleaut32.inc
    ;       includelib \MASM32\LIB\oleaut32.lib
    ;
    ; --------------------------------------------------
      stralloc MACRO ln
        invoke SysAllocStringByteLen,0,ln
      ENDM

      strfree MACRO strhandle
        invoke SysFreeString,strhandle
      ENDM

    ; -------------------------------------------------------------------
    ; The following 2 macros are for limiting the size of a window while
    ; it is being resized. They are to be used in the WM_SIZING message.
    ; -------------------------------------------------------------------
    LimitWindowWidth MACRO wdth
        LOCAL label
        mov eax, lParam
        mov ecx, (RECT PTR [eax]).right
        sub ecx, (RECT PTR [eax]).left
        cmp ecx, wdth
        jg label
      .if wParam == WMSZ_RIGHT || wParam == WMSZ_BOTTOMRIGHT || wParam == WMSZ_TOPRIGHT
        mov ecx, (RECT PTR [eax]).left
        add ecx, wdth
        mov (RECT PTR [eax]).right, ecx
      .elseif wParam == WMSZ_LEFT || wParam == WMSZ_BOTTOMLEFT || wParam == WMSZ_TOPLEFT
        mov ecx, (RECT PTR [eax]).right
        sub ecx, wdth
        mov (RECT PTR [eax]).left, ecx
      .endif
      label:
    ENDM

    LimitWindowHeight MACRO whgt
        LOCAL label
        mov eax, lParam
        mov ecx, (RECT PTR [eax]).bottom
        sub ecx, (RECT PTR [eax]).top
        cmp ecx, whgt
        jg label
      .if wParam == WMSZ_TOP || wParam == WMSZ_TOPLEFT || wParam == WMSZ_TOPRIGHT
        mov ecx, (RECT PTR [eax]).bottom
        sub ecx, whgt
        mov (RECT PTR [eax]).top, ecx
      .elseif wParam == WMSZ_BOTTOM || wParam == WMSZ_BOTTOMLEFT || wParam == WMSZ_BOTTOMRIGHT
        mov ecx, (RECT PTR [eax]).top
        add ecx, whgt
        mov (RECT PTR [eax]).bottom, ecx
      .endif
      label:
    ENDM

    ; ---------------------------------------
    ; Append literal string to end of buffer
    ; ---------------------------------------
      Append MACRO buffer,text
        LOCAL szTxt
        .data
          szTxt db text,0
        .code
        invoke szCatStr,ADDR buffer,ADDR szTxt
      ENDM

    ; ---------------------------
    ; Put ascii zero at 1st byte
    ; ---------------------------
      zero1 MACRO membuf
        mov membuf[0], 0
      ENDM

    ; -------------------------
    ; Application startup code
    ; -------------------------
      AppStart MACRO
        .code
        start:
        invoke GetModuleHandle, NULL
        mov hInstance, eax

        invoke GetCommandLine
        mov CommandLine, eax

        invoke InitCommonControls

        invoke WinMain,hInstance,NULL,CommandLine,SW_SHOWDEFAULT
        invoke ExitProcess,eax
      ENDM

      ShellAboutBox MACRO handle,IconHandle,quoted_Text_1,quoted_Text_2:VARARG
        LOCAL AboutTitle,AboutMsg,buffer

        .data
          AboutTitle db quoted_Text_1,0
          AboutMsg   db quoted_Text_2,0
          buffer db 128 dup (0)
        .code

        mov esi, offset AboutTitle
        mov edi, offset buffer
        mov ecx, lengthof AboutTitle
        rep movsb
        
        invoke ShellAbout,handle,ADDR buffer,ADDR AboutMsg,IconHandle
      ENDM

    ; --------------------------------------------------------------
    ; Specifies processor, memory model & case sensitive option.
    ; The parameter "Processor" should be in the form ".386" etc..
    ; EXAMPLE : AppModel .586
    ; --------------------------------------------------------------
      AppModel MACRO Processor
        Processor             ;; Processor type
        .model flat, stdcall  ;; 32 bit memory model
        option casemap :none  ;; case sensitive
      ENDM

    ; --------------------------------------------
    ; The following two macros must be used as a
    ; pair and can only be used once in a module.
    ; Additional code for processing within the
    ; message loop can be placed between them.
    ;
    ; The single parameter passed to both macros
    ; is the name of the MSG structure and must be
    ; the same in both macros.
    ; --------------------------------------------

      BeginMessageLoop MACRO mStruct
        MessageLoopStart:
          invoke GetMessage,ADDR mStruct,NULL,0,0
          cmp eax, 0
          je MessageLoopExit
      ENDM

      EndMessageLoop MACRO mStruct
          invoke TranslateMessage, ADDR mStruct
          invoke DispatchMessage,  ADDR mStruct
          jmp MessageLoopStart
        MessageLoopExit:
      ENDM

    ; --------------------------------------------------------
    ; MsgBox macro takes 2 parameters, both can be either
    ; literal text in quotes or addresses of zero terminated
    ; strings passed with "ADDR szString" where szString is
    ; a zero terminated string. Note that ADDR is uppercase.
    ;
    ; example : MsgBox "Greetings all",ADDR szTitle
    ;           MsgBox ADDR szMessage,"Result"
    ;
    ; --------------------------------------------------------

      MsgBox MACRO handl, TxtMsg, TxtTitle, styl

        LOCAL Msg1
        LOCAL Titl

        If @InStr(1,<TxtMsg>,<ADDR>) eq 0
          If @InStr(1,<TxtTitle>,<ADDR>) eq 0
          .data
            Msg1 db TxtMsg,0
            Titl db TxtTitle,0
          .code
            invoke MessageBox,handl,ADDR Msg1,ADDR Titl,styl
            EXITM
          EndIf
        EndIf

        If @InStr(1,<TxtMsg>,<ADDR>) gt 0
          If @InStr(1,<TxtTitle>,<ADDR>) eq 0
          .data
            Titl db TxtTitle,0
          .code
            invoke MessageBox,handl,TxtMsg,ADDR Titl,styl
            EXITM
          EndIf
        EndIf

        If @InStr(1,<TxtMsg>,<ADDR>) eq 0
          If @InStr(1,<TxtTitle>,<ADDR>) gt 0
          .data
            Msg1 db TxtMsg,0
          .code
            invoke MessageBox,handl,ADDR Msg1,TxtTitle,styl
            EXITM
          EndIf
        EndIf

        If @InStr(1,<TxtMsg>,<ADDR>) gt 0
          If @InStr(1,<TxtTitle>,<ADDR>) gt 0
            invoke MessageBox,handl,TxtMsg,TxtTitle,styl
            EXITM
          EndIf
        EndIf

      ENDM

    ; -------------------------------------------
    ; put zero terminated string in .data section
    ; alternative to the szText MACRO
    ; -------------------------------------------
      dsText MACRO Name, Text:VARARG
      .data
        Name db Text,0
      .code
      ENDM

    ; -------------------------------
    ; make 2 WORD values into a DWORD
    ; result in eax
    ; -------------------------------
      MAKEDWORD MACRO LoWord,HiWord
        mov ax, HiWord
        ror eax, 16
        mov ax, LoWord
      ENDM

    ; -----------------------------
    ; return IMMEDIATE value in eax
    ; -----------------------------
      retval MACRO var
        IF var EQ 0
          xor eax, eax  ;; slightly more efficient for zero
        ELSE
          mov eax, var  ;; place value in eax
        ENDIF
      ENDM

    ; ------------------------
    ; inline memory copy macro
    ; ------------------------
      Mcopy MACRO lpSource,lpDest,len
        mov esi, lpSource
        mov edi, lpDest
        mov ecx, len
        rep movsb
      ENDM

    ;; -----------------------------------
    ;; INPUT red, green & blue BYTE values
    ;; OUTPUT DWORD COLORREF value in eax
    ;; -----------------------------------
      RGB MACRO red, green, blue
        xor eax, eax
        mov al, blue    ; blue
        rol eax, 8
        mov al, green   ; green
        rol eax, 8
        mov al, red     ; red
      ENDM

    ; ------------------------------------------------
    ; The following macro were written by Ron Thomas
    ; ------------------------------------------------
    ; Retrieves the low word from double word argument
    ; ------------------------------------------------
      LOWORD MACRO bigword  
        mov  eax,bigword
        and  eax,0FFFFh     ;; Set to low word 
      ENDM

    ; ----------------------
    ; fast lodsb replacement
    ; ----------------------
      lob MACRO
        mov al, [esi]
        inc esi
      ENDM

    ; ----------------------
    ; fast stosb replacement
    ; ----------------------
      stb MACRO
        mov [edi], al
        inc edi
      ENDM

    ; -------------------------------
    ; pascal calling convention macro
    ; left to right push
    ; -------------------------------
      Pcall MACRO name:REQ,items:VARARG
        LOCAL arg
        FOR arg,<items>
          push arg
        ENDM
          call name
      ENDM

; ------------------------------------------------------------------
; macro for making STDCALL procedure and API calls.
; ------------------------------------------------------------------

Scall MACRO name:REQ,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12, \
                     p13,p14,p15,p16,p17,p18,p19,p20,p21,p22

    ;; ---------------------------------------
    ;; loop through arguments backwards, push
    ;; NON blank ones and call the function.
    ;; ---------------------------------------

    FOR arg,<p22,p21,p20,p19,p18,p17,p16,p15,p14,p13,\
             p12,p11,p10,p9,p8,p7,p6,p5,p4,p3,p2,p1>
      IFNB <arg>    ;; If not blank
        push arg    ;; push parameter
      ENDIF
    ENDM

    call name       ;; call the procedure

ENDM

; ---------------------------------------------------------------------
;
; The GLOBALS macro is for allocating uninitialised data in the .DATA?
; section. It is designed to take multiple definitions to make
; allocating uninitialised data more intuitive while coding.
;
; EXAMPLE: GLOBALS item1 dd ?,\
;                  item2 dd ?,\
;                  item3 dw ?,\
;                  item4 db 128 dup (?)
;
; ---------------------------------------------------------------------

      GLOBALS MACRO var1,var2,var3,var4,var5,var6,var7,var8,var9,var0,
                    varA,varB,varC,varD,varE,varF,varG,varH,varI,varJ
        .data?
          var1
          var2
          var3
          var4
          var5
          var6
          var7
          var8
          var9
          var0
          varA
          varB
          varC
          varD
          varE
          varF
          varG
          varH
          varI
          varJ
        .code
      ENDM


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值