如何在MASM中为一个项目编写和组合多个源文件?

2024-03-17

对于组装来说还是个新手,玩起来很有趣。我想将程序的功能拆分到多个文件中,特别是通过将类似的功能分组在一起进行组织。这些其他文件将由主文件(甚至希望其他非主文件)调用。我还没有成功,希望得到帮助。

我不使用 IDE,更喜欢使用 notepad++、ml.exe 和 link.exe(来自 MASM 文件夹)自己编写、汇编和链接程序。我看过的大多数在线资源都假设 Visual Studio,并提供对我不起作用的代码,或者可能是不完整的,因为 IDE 做了其他事情。我不打算开始使用 IDE。

我想学习“最好”的方式,即对未来项目最有用的方式。我可以将其设置为只需复制文件并编写几行代码即可在将来的不同项目中使用它吗?或者也许这是不好的做法,我应该学习一种更标准的方法?我知道这个平台不适合提出固执己见的问题,我希望这个问题比意见更基于事实。

我能想到的所有有用信息:
语言:Masm 汇编 x86
计算机:64位Windows

代码:

运行.bat

@echo off

ml /c /coff /Zi /Fl Driver.asm
ml /c /coff /Zi /Fl Utils.asm

link /debug /subsystem:console /entry:start /out:Driver.exe Utils.obj Driver.obj \masm32\lib\kernel32.lib

Driver.exe

pause

驱动程序.asm

.386
.model flat
.stack 100h

ExitProcess PROTO Near32 STDCALL, dwExitCode:DWORD
ClearRegs PROTO

.DATA
.CODE

PUBLIC _start
_start:

    Main PROC
        MOV EAX, 0
        INVOKE ClearRegs
        INVOKE ExitProcess, 0
    Main ENDP

END

实用程序.asm

.386
.model flat
.stack 100h

OPTION PROC:PRIVATE ; Set procedures to private by default

PUBLIC ClearRegs

.DATA
.CODE
    
    ClearRegs PROC C
        XOR EAX, EAX
        XOR EBX, EBX
        XOR ECX, ECX
        XOR EDX, EDX
        XOR ESI, ESI
        XOR EDI, EDI
        RET
    ClearRegs ENDP

END

端子输出

Microsoft (R) Macro Assembler Version 6.14.8444
Copyright (C) Microsoft Corp 1981-1997.  All rights reserved.

 Assembling: Driver.asm
Microsoft (R) Macro Assembler Version 6.14.8444
Copyright (C) Microsoft Corp 1981-1997.  All rights reserved.

 Assembling: Utils.asm
Microsoft (R) Incremental Linker Version 5.12.8078
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

Driver.obj : error LNK2001: unresolved external symbol ClearRegs
Driver.exe : fatal error LNK1120: 1 unresolved externals
'Driver.exe' is not recognized as an internal or external command,
operable program or batch file.
Press any key to continue . . .

现在您的问题已经用最小的、完整的、可验证的示例进行了更新,可以识别一些特定的问题。当你声明一个函数时PROC每个函数都有一个语言命名和调用约定。不指定则表示不进行特殊处理。

您可以使用模型指令作为第二个参数指定默认语言。在您使用的两个文件中:

.model flat

所以您还没有关联默认语言。你已经定义了ClearRegs as:

ClearRegs PROC C
[snip]
ClearRegs ENDP

这里的问题是PROC C指定C语言调用约定和命名约定。采用 COFF 格式(32 位)C命名约定需要下划线(_) 添加到函数名称的开头。如果您要生成 MAP 文件,您会发现从导出的函数名称实用程序.asm实际上是_ClearRegs并不是ClearRegs.

有很多方法可以解决这个问题。您可以选择不添加默认语言.model指示和告诉Driver.asm that ClearRegs被定义为C通过更改原型:

ClearRegs PROTO

to

ClearRegs PROTO C

So now 实用程序.asm正在出口_ClearRegs and 驱动程序.asm正在导入_ClearRegs当双方匹配时,MASM 将处理添加额外的下划线。INVOKE ClearRegs将使用与相关的命名约定PROTO声明说语言是C所以它会添加额外的_为你。

这会带来您可以进行的额外更改。一个END指令可用于指定程序的入口点,而不是使用/entry:<name>在链接器命令行上。入口点的名称必须以_以满足链接器的要求。

您当前使用此功能驱动程序.asm:

PUBLIC _start
_start:

Main PROC
    [snip]
Main ENDP

END

而你用/entry:start链接时。您可以将其更改为:

_Main PROC
    [snip]
_Main ENDP

END _Main   ; END with a function name tells linker to use _Main as program entry point

链接时您现在可以删除/entry完全选项,你不需要_start标签不再。不过我们可以做得更好。 MS调用的入口点C运行时启动假设该函数遵循C语言命名和调用约定。最好是这样做:

Main PROC C
    [snip]
Main ENDP

END Main   ; END with a function name tells linker to use _Main as program entry point

如果你打算让你的所有功能PROC C那么你可以避免指定C在大多数地方通过更改默认语言实用程序.asm and 驱动程序.asm通过改变:

.model flat

to:

.model flat, C

这将更改默认值PROTO声明,PUBLIC指定函数定义的语句PROC and PROC陈述本身。你的代码在驱动程序.asm可能看起来像:

.386
.model flat, C
.stack 100h

ExitProcess PROTO Near32 STDCALL, dwExitCode:DWORD
ClearRegs PROTO

.DATA
.CODE

Main PROC
    MOV EAX, 0
    INVOKE ClearRegs
    INVOKE ExitProcess, 0
Main ENDP

END Main

实用程序.asm可能看起来像:

.386
.model flat, C
.stack 100h

OPTION PROC:PRIVATE ; Set procedures to private by default

PUBLIC ClearRegs

.DATA
.CODE
    
ClearRegs PROC
    XOR EAX, EAX
    XOR EBX, EBX
    XOR ECX, ECX
    XOR EDX, EDX
    XOR ESI, ESI
    XOR EDI, EDI
    RET
ClearRegs ENDP

END

你会链接到:

link /debug /subsystem:console /out:Driver.exe Utils.obj Driver.obj \masm32\lib\kernel32.lib
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在MASM中为一个项目编写和组合多个源文件? 的相关文章

  • 以编程方式或使用清单 (MinGW) 将“覆盖高 DPI 缩放”设置为“系统(增强)”

    我尝试了所有可能的组合gdiScaling and dpiAware 仍然没有运气 如果我手动右键单击 app exe 并将 覆盖高 DPI 缩放 设置为 系统 增强 效果很好
  • orpd等SSE2指令有什么意义?

    The orpd指令是 压缩双精度浮点值的按位逻辑或 这不是做完 全相同的事情吗por 按位逻辑或 如果是这样 拥有它还有什么意义呢 请记住 SSE1orps https www felixcloutier com x86 orps首先 实
  • 将两个 32 位整数向量相乘,生成 32 位结果元素向量

    将每个 32 位条目乘以 2 的最佳方法是什么 mm256i互相注册 mm256 mul epu32不是我正在寻找的 因为它产生 64 位输出 我想要每个 32 位输入元素都有一个 32 位结果 而且 我确信两个 32 位值的乘法不会溢出
  • 奇怪的 MSC 8.0 错误:“ESP 的值未在函数调用中正确保存...”

    我们最近尝试将一些 Visual Studio 项目分解为库 并且在测试项目中一切似乎都编译和构建得很好 其中一个库项目作为依赖项 然而 尝试运行该应用程序给我们带来了以下令人讨厌的运行时错误消息 运行时检查失败 0 ESP 的值未在函数调
  • Xcode -- 让force_load 使用相对路径

    某些库在链接到 Xcode 项目时需要 all load 链接器标志 但是 如果库之间存在符号冲突 这会导致链接器错误 解决方案是使用 force load 它可以有效地让您在某些库上使用 all load 但不能在其他库上使用 然而 这反
  • 如何重命名共享库以避免同名冲突?

    我找到了一个图书馆 libjson http sourceforge net projects libjson 我正在尝试将其构建为共享库并在项目中使用 建造很简单 修复 Makefile 错误后 SHARED 1 make install
  • 当用户拖动列表视图项目时检测何时需要滚动

    介绍 我正在实现列表视图项目的重新排列 而不使用 OLE 拖放 PROBLEM 我已经成功解决了大部分任务 除了当用户想要将项目放置在当前不可见的位置时向上 向下滚动之外 问题 我可以使用以下消息向上 向下滚动列表视图 SendMessag
  • 为什么 RISC-V S-B 和 U-J 指令类型以这种方式编码?

    我正在读一本书 计算机组织与设计RISC V版 我遇到了 S B 和 U J 指令类型的编码 我上面提到的那些类型有奇怪的编码立即字段 S B 类型将直接字段分为两部分 这是有道理的 因为所有指令编码都必须相似 但我无法理解为什么立即字段以
  • winapi 函数的函数指针 (stdcall/cdecl)

    请有人给我一些为 MS winapi 函数创建函数指针的提示吗 我试图为 DefWindowProc DefWindowProcA DefWindowProcW 创建一个指针 但出现此错误 LRESULT dwp HWND UINT WPA
  • 当我打开在 Xcode 4 中创建的 Google 地图项目时,Xcode 5 会警告我的架构设置

    我刚刚更新到新发布的 Xcode 5 我正在开发一个使用 Google 地图 iOS SDK 的 iOS 应用程序 当我在 Xcode 4 中开发时 我改变了我的Architectures在我的项目设置中进行设置 按照 Google 的步骤
  • 如何获取当前所选键盘布局的显示名称

    我需要以语言栏显示输入语言的方式向用户显示输入语言列表 例如 目前我有 class Program static void Main string args var langs InputLanguage InstalledInputLan
  • Windows 8 SDK 中的 DirectX

    Summary 是否应该从针对 Windows 8 的应用程序中删除 directX 包含文件 Details 我是 Windows 开发新手 我正在尝试使用 Visual Studio 2012 如果可能 在 Windows 8 上编译
  • C++ 检查 unicode 字符是否为全角

    如何检查unicode字符是否是全角 我使用Win32 MFC 例如 中是全宽 A不是全角 是全宽 F不是全宽 你需要的是检索东亚宽度 http www unicode org reports tr11 的角色 您可以通过解析来做到这一点东
  • 如何用C语言测量时间?

    我想知道某个代码块执行了多长时间 大约 像这样的事情 startStopwatch do some calculations stopStopwatch printf lf timeMesuredInSeconds How 您可以使用clo
  • 在 C++ 程序中多次使用 FindWindows?

    我使用以下代码 C 来获取窗口 另一个应用程序 的句柄并向其中一个按钮发送消息以模拟单击 并且它可以正常工作 BOOL CALLBACK EnumChildProc HWND hwnd LPARAM lParam mdv test list
  • win32 内容已更改,但除非移动窗口,否则不会显示更新

    我的 win32 GUI 内容每秒都会更改 但除非手动移动窗口 否则不会显示更新 我尝试每秒弹出一个消息框来触发窗口刷新 它成功了 因此 这证明我的内容确实发生了变化 但窗口没有更新 我希望刷新窗口而不是每次都弹出消息框 有没有这样的窗口功
  • 为什么 SetCursorPos 将光标位置重置到显示屏的左侧?

    SetCursorPos https learn microsoft com en us windows win32 api winuser nf winuser setcursorpos将光标移动到指定的屏幕坐标 然而 它似乎有一个错误
  • 屏幕截图忽略了一些窗口

    我正在 MFC 中工作 我正在尝试捕获桌面的 bmp 我正在使用 GetDC NULL 来执行此操作 但它似乎忽略了特殊的皮肤窗口 它似乎忽略了用 UpdateLayeredWindow 绘制的窗口 此行为似乎仅发生在 Vista x64
  • Intel 64 和 IA-32 上的 MESI 有何意义

    MESI 的要点是保留共享内存系统的概念 然而 对于存储缓冲区 事情就变得复杂了 一旦数据到达 MESI 实现的缓存 下游内存就会保持一致 然而 在此之前 每个核心可能对内存位置 X 中的内容存在分歧 具体取决于每个核心的本地存储缓冲区中的
  • 通过 cmake 链接 libc++ 时 libc++abi 的链接问题

    我正在尝试构建一个简单的 hello world C 使用 LLVM Clang 3 7 0 的程序 根据工具链的源代码构建libc 使用命令行 clang std c 14 stdlib libc fno exceptions hello

随机推荐

  • Pandaboard 交叉编译 Qt

    我花了几周的时间尝试为我的 Panda 板交叉编译 Qt 但没办法 我无法通过 configure 如果有人能给我帮助 我将不胜感激 我的主机系统是Ubuntu 13 04 86 64位 在Virtualbox中运行 我的目标系统是 Pan
  • Python 中的舍入是如何工作的?

    我对 Python 中舍入的工作原理有点困惑 有人能解释一下为什么Python会这样吗 Example gt gt gt round 0 05 1 this makes sense 0 1 gt gt gt round 0 15 1 thi
  • 转换文件:Android 中的 Uri 到文件

    转换的最简单方法是什么android net Uri https developer android com reference android net Uri持有一个对象file 键入一个java io File https develo
  • “在源 Y 中找不到事件 ID X 的描述。”

    我正在尝试将自定义事件从我的 Web 应用程序写入 Windows 事件日志 我没有运气让消息字符串正常工作 我不断收到 无法找到源 Y 中事件 ID X 的描述 为了缩小范围 我决定将一个事件写入我的机器上已存在的源 我只是查看了已经写出
  • Nginx 配置中静态位置的多个位置

    我的应用程序将在两个位置提供静态文件 一个是 my path project static 另一个是 my path project jsutils static 我很难让网络服务器在两个目录中查找静态内容 这是我的应用程序的 nginx
  • UICollectionView 动画(插入/删除项目)

    我想在插入和 或删除 UICollectionViewCell 时自定义动画样式 我需要这个的原因是 默认情况下 我看到插入单元格的动画具有平滑的淡入淡出效果 但是删除单元格具有向左移动 淡出动画的组合 如果不是因为一个问题 我会对此感到非
  • 使用具有多个比较器的比较器

    我可以使用此代码中的所有简单比较器进行排序 但不能ComplexComparator 我不知道如何编码才能使其正常工作 任何建议 解释将不胜感激 这是我的主要程序 package pkgTest import java util Array
  • 如何使用 Elasticsearch 编写条件查询?

    我有一个简单的 Elasticsearch JSON 查询 如下所示 query bool must match id 1 must match tags name a1 仅当值 本例中为 a1 不为空时 如何执行第二个 必须 条件 您可以
  • IBM Blockchain Marble 演示中的交易存储在哪里?

    我正在运行下面链接中提到的 IBM 提供的区块链演示 https github com IBM Blockchain marbles https github com IBM Blockchain marbles 我在一个 Linux 系统
  • 如何从 Firestore 查询中排除元素?

    我有一个用户集合 我想从数据库中查询所有用户并将它们显示在RecyclerView除了一个 mine 这是我的数据库架构 users collection uid document uid fR5bih7SysccRu2Gu9990TeSS
  • 如何像对象一样操作Json响应?

    我的 jQuery ajax 返回 JSon 对象 我首先阅读了其他文章 但他们的回复文字不喜欢我的 我的回复内容 来自萤火虫响应 item country USA lan EN country Turkiye lan TR 现在我试图提醒
  • 通过内省打印 ctypes“Structure”的所有字段

    test c include
  • 在 XAML (WPF) 中将图标放入文本框中

    我想将一个小图标 一个 png 文件 放在文本框的一角 我的意思的草图位于http dosketch com view php k mIPeHLSBLx0e2YpoVpYO http dosketch com view php k mIPe
  • 创建自定义链轮处理器的文档?

    我正在尝试为 Rails 创建一个链轮预处理器 它会发现 png rb资产管道中的文件 并使用它们生成我的应用程序中各个页面的 png 屏幕截图 我已经阅读了很多关于这个主题的内容 但我似乎找不到任何关于如何进行此设置的简单文档 请帮助 这
  • 在 Active Record 中使用 find() 和多个 where 子句

    我想将 Active Record 查询后的内容 使用括号 分为 3 组 第一组是从第一个 Where 子句到最后一个 orWhere 第二个和第三个将使用 andWhere 请给我关于如何使用括号分隔所有 3 个部分的建议 query B
  • UICollectionView 不调用委托方法

    我已经设置了一个UICollectionView在故事板中并连接数据源和委托出口 我已经通过笔尖注册了一个单元格 我将其出队cellForItemAtIndexPath 方法 所有工作都完美地期望委托方法永远不会被调用 例如 当触摸一个单元
  • 如何在 Javascript 中实现应用模式

    Javascript 中引用函数调用模式的应用调用模式是什么 我该如何使用它 使用这种调用模式有什么好处 指某东西的用途apply与函数上下文相关 this关键字 和参数传递 首先 我想你应该知道在什么情况下this关键字是隐含地 set
  • 如何从 ~/.aws/config 加载配置

    变更日志 https github com aws aws sdk js blob master CHANGELOG md 2440 says Load config from aws config if AWS SDK LOAD CONF
  • ListField 在编辑/创建帖子中显示

    我正在一个项目中使用 Flask mongoengine 我正在尝试从中获取基本的东西http docs mongodb org manual tutorial write a tumblelog application with flas
  • 如何在MASM中为一个项目编写和组合多个源文件?

    对于组装来说还是个新手 玩起来很有趣 我想将程序的功能拆分到多个文件中 特别是通过将类似的功能分组在一起进行组织 这些其他文件将由主文件 甚至希望其他非主文件 调用 我还没有成功 希望得到帮助 我不使用 IDE 更喜欢使用 notepad