masm x86汇编 资源混合编译

Posted 不会写代码的丝丽

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了masm x86汇编 资源混合编译相关的知识,希望对你有一定的参考价值。

和rc资源进行混编

我们在日常编程的时候经常使用rc来写一些dialog快捷键等。本节展示如何在其混镖环境下使用这个rc资源.

如果你使用ml来进行编译,并且使用高版本的visual studio来编辑rc文件,那么请安装XP支持组件
这里直接使用vc6.0来进行

我保存后得到两个文件

resource.h
resouce.rc

我们将h文件转化为汇编的头文件

//resource.h
//NO_DEPENDENCIES
// Microsoft Developer Studio generated include file.
// Used by myresouce.rc
//
#define BTN_TEST                        3
#define IDD_DIALOG1                     101

// Next default values for new objects
// 
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        102
#define _APS_NEXT_COMMAND_VALUE         40001
#define _APS_NEXT_CONTROL_VALUE         1000
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif

转化后

;resource.inc
IDD_DIALOG1          equ           101
_APS_NEXT_RESOURCE_VALUE    equ    102
_APS_NEXT_COMMAND_VALUE     equ    40001
_APS_NEXT_CONTROL_VALUE      equ   1000
_APS_NEXT_SYMED_VALUE       equ    101
BTN_TEST            equ            3

最后编写我们的汇编代码

.386
.model flat,stdcall
option casemap:NONE

include windows.inc
include user32.inc
include kernel32.inc
include resource.inc

includelib user32.lib
includelib kernel32.lib

.data
    g_hInst dd 0
    g_szText db "button is clicked",0



    
.code

MyDlgProc proc hWndDlg:HWND,uMsg:UINT,wParam:WPARAM,LParam:LPARAM

    .IF uMsg ==WM_CLOSE
        invoke EndDialog,hWndDlg,0
    .ELSEIF uMsg ==WM_COMMAND
        mov eax,wParam
        .IF ax == BTN_TEST
            invoke MessageBoxA,NULL,offset  g_szText,NULL,MB_OK
        .ENDIF
    .ENDIF

    mov eax,FALSE
    ret
MyDlgProc endp 



START:
    ;获取进程句柄
    invoke GetModuleHandleA,NULL
    mov g_hInst,eax
    
    invoke DialogBoxParamA,g_hInst,IDD_DIALOG1,NULL,offset MyDlgProc,0



    invoke ExitProcess,0

end START

执行编译

rc myresouce.rc
ml /c /coff my32.asm
link /subsystem:windows  my32.obj myresouce.RES

c调用汇编

.386
.model flat,stdcall
option casemap:NONE

.code
myAddFun proc arg1:dword,arg2:dword
    mov eax,arg1
    add eax,arg2
    ret
myAddFun endp 
end

编译成obj后拖入vs中


执行函数声明并调用

extern "C" int __stdcall myAddFun(int, int);

int main()

	int ret = myAddFun(1, 2);
    std::cout << "Hello World!\\n"<<ret<<std::endl;

汇编调用c

请使用vc6.0编译减少链接问题

编写如下代码

编译后得到myfun.obj 放入汇编目录并写入如下代码

.386
.model flat,stdcall
option casemap:NONE


myAddFun proto arg1:dword,arg2:dword

.code

Start:
    invoke myAddFun, 2,3


end Start
```.386
.model flat,stdcall
option casemap:NONE


myAddFun proto arg1:dword,arg2:dword

.code

Start:
    invoke myAddFun, 2,3


end Start
ml /c /coff  xx.asm
link  /subsystem:console myfun.obj xx.obj 

调用一些系统库例子

.386
.model flat,stdcall
option casemap:NONE

include windows.inc
include user32.inc
include kernel32.inc
include msvcrt.inc

includelib user32.lib
includelib kernel32.lib
includelib msvcrt.lib

.data
    g_hInst dd 0
    g_szText db "button is clicked",0
    g_szFmt db "%s %d",0dh,0ah,0
    
.code

START:
    ;获取进程句柄
    invoke GetModuleHandleA,NULL
    mov g_hInst,eax
    
    ; invoke DialogBoxParamA,g_hInst,IDD_DIALOG1,NULL,offset MyDlgProc,0
    invoke crt_strlen,offset g_szText
    invoke crt_printf,offset g_szFmt,offset g_szText,eax


    invoke ExitProcess,0

end START

生产一个dll

.386
.model flat,stdcall
option casemap:NONE

include windows.inc
include user32.inc
include kernel32.inc
include msvcrt.inc

includelib user32.lib
includelib kernel32.lib
includelib msvcrt.lib

.data
    g_hInst dd 0
    g_szText db "button is clicked",0
    g_szFmt db "%s %d",0dh,0ah,0
    
.code

PrintText proc
    invoke crt_strlen,offset g_szText
    invoke crt_printf,offset g_szFmt,offset g_szText,eax
    ret
PrintText endp



DllMain proc hinstDLL:HINSTANCE, fdwReason:DWORD,lpReserved:LPVOID
    mov eax,TRUE
    ret
DllMain endp




end DllMain
EXPORTS
    PrintText
/dll 命令用于生产一个dll不然会生产exe  /def用于指定导出
link  /subsystem:windows /dll  my32.obj /def:test.def

我们写一个例子进行调用

.386
.model flat,stdcall
option casemap:NONE


include windows.inc
include user32.inc
include kernel32.inc
include msvcrt.inc

includelib user32.lib
includelib kernel32.lib
includelib msvcrt.lib


PrintText proto


.code

Start:
    invoke PrintText
    invoke ExitProcess,0
end Start

在链接时加上lib库即可

link  /subsystem:console invoke.obj my32.lib

实现一个win32最小化程序

.386
.model flat,stdcall
option casemap:NONE

include windows.inc
include user32.inc
include kernel32.inc
include msvcrt.inc

includelib user32.lib
includelib kernel32.lib
includelib msvcrt.lib

.data
    g_szWndClass db "xxsswndClass",0
    g_szTitle db "title",0
    
.code

MyDlgProc proc stdcall hWndDlg:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
    .IF uMsg==WM_CLOSE
      invoke  PostQuitMessage,0
    .ENDIF

    invoke DefWindowProc,hWndDlg,uMsg,wParam,lParam
    ret
MyDlgProc endp 


WinMain proc   hInst:HINSTANCE ,
               hPrevInstance:HINSTANCE ,
               lpCmdLine:LPWSTR ,
               nCmdShow:DWORD
    local  @wc:WNDCLASS
    local  @msg:MSG
    ;注册窗口类
    ;清空内存用0去填充
    invoke RtlZeroMemory,addr @wc,type @wc
    ;窗口风格
    mov @wc.style,CS_HREDRAW or CS_VREDRAW
    ;窗口过程 
    mov @wc.lpfnWndProc ,offset MyDlgProc
    ;hInst 是内存 wc也是内存,但是汇编不允许内存直接到内存。workaround 应对内存到内存
    push hInst
    pop @wc.hInstance

    mov @wc.hbrBackground,COLOR_GRAYTEXT
    mov @wc.lpszClassName,offset g_szWndClass


    invoke RegisterClassA,addr @wc

    .IF eax==0
        ret
    .ENDIF

 
    ;创建窗口实例
    invoke CreateWindowExA,
                        0, 
                        offset g_szWndClass,
                        offset g_szTitle,
                        WS_OVERLAPPEDWINDOW or WS_VISIBLE,
                        CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
                        NULL,
                        NULL,
                        hInst,
                        NULL


    .IF eax ==  NULL
        ret
    .ENDIF

    ;消息循环
    .WHILE TRUE
        invoke GetMessage,addr @msg,NULL,0,0
        .IF eax==0
            ret
        .ENDIF

        invoke DispatchMessage,addr @msg
    .ENDW


WinMain endp

START:
    invoke GetModuleHandleA,NULL
    invoke WinMain,eax,NULL,NULL,NULL
    invoke ExitProcess,0

end START

以上是关于masm x86汇编 资源混合编译的主要内容,如果未能解决你的问题,请参考以下文章

使用 TYPE 指令汇编 MASM x86

需要帮助使用 masm 以 80x86 汇编语言连接两个字符串

Debug和汇编编译器masm对指令的不同处理

vs2017下汇编环境配置

x86汇编编程中如何表示FFFFFFBB等十六进制值?

x86汇编编程中如何表示FFFFFFBB等十六进制值?