MinGW的ld无法对非PE输出文件执行PE操作

2024-02-13

我知道还有一些其他类似的问题,无论是否是 StackOverflow。我为此进行了很多研究,但仍然没有找到单一的解决方案。 我正在做一个操作系统作为一个业余项目。我一直在汇编中完成所有工作,但现在我想加入 C 代码。 为了测试,我制作了这个汇编代码文件(称为 test.asm):

[BITS 32]

GLOBAL _a

SECTION .text

_a:
    jmp $

然后我制作了这个 C 文件(称为 main.c):

extern void a(void);
int main(void)
{
    a();
}

为了链接,我使用了这个文件(称为 make.bat):

"C:\minGW\bin\gcc.exe"  -ffreestanding -c -o c.o main.c
nasm -f coff -o asm.o test.asm
"C:\minGW\bin\ld.exe" -Ttext 0x100000 --oformat binary -o out.bin c.o asm.o

pause

我已经研究了很多年,但仍在努力寻找答案。我希望这不会被标记为重复。我承认存在类似的问题,但都有不同的答案,而且没有一个对我有用。

问题:我究竟做错了什么?


旧的 MinGW 版本存在“ld”根本无法创建非 PE 文件的问题。

也许当前版本也有同样的问题。

解决方法是使用“ld”创建一个 PE 文件,然后使用“objcopy”将 PE 文件转换为二进制、十六进制或 S19。

- - 编辑 - -

再次思考这个问题我发现两个问题:

正如我已经说过的,某些版本的“ld”在创建“二进制”输出(而不是“PE”、“ELF”或任何使用的格式)时存在问题。

代替:

ld.exe --oformat binary -o file.bin c.o asm.o

您应该使用以下顺序来创建二进制文件:

ld.exe -o file.tmp c.o asm.o
objcopy -O binary file.tmp file.bin

这将创建一个名为“binary.tmp”的“.exe”文件;那么“objcopy”将从“.exe”文件创建原始数据。

第二个问题是链接本身:

“ld”采用类似“.exe”的文件格式 - 即使输出文件是二进制文件。这意味着 ...

  • ...您甚至无法确定“main.o”的目标代码是否确实放置在结果目标代码的首地址处。 “ld”还可以将“a()”的代码放在“main()”之前,甚至可以将“内部”代码放在“a()”和“main()”之前。
  • ...寻址的工作方式有点不同,这意味着如果您做错了什么,将会创建大量填充字节(可能在文件的开头!)。

我看到的唯一可能性是创建一个“链接器脚本”(有时称为“链接器命令文件”)并在汇编器代码中创建一个特殊部分(因为我通常使用“nasm”之外的另一个汇编器,我不知道语法是否这里是正确的):

[BITS 32]
GLOBAL _a
SECTION .entry
    jmp _main
SECTION .text
_a:
    jmp $

在链接描述文件中,您可以指定哪些节以何种顺序出现。指定“.entry”是文件的第一部分,这样您就可以确定它是文件的第一条指令。

在链接器脚本中,您也可能会说多个部分(例如“.entry”、“.text”和“.data”)应组合成一个部分。这很有用,因为 PE 文件中的节通常是 0x1000 字节对齐的!如果您不将多个部分合并为一个部分,您将在各部分之间获得大量存根字节!

不幸的是,我不是链接器脚本方面的专家,因此我无法为您提供太多帮助。

使用“-Ttext”也有问题:

在PE文件中,节的实际地址计算为“图像基址”+“相对地址”。 “-Ttext”参数只会影响“相对地址”。因为在 Windows 中,第一节的“相对地址”通常固定为 0x1000,所以“-Ttext 0x2000”除了在第一节的开头填充 0x1000 存根字节之外什么也不做。但是,您根本不会影响“.text”的起始地址 - 您只需在“.text”部分的开头填充存根字节,以便第一个useful字节位于 0x2000。 (也许某些“ld”版本的行为有所不同。)

如果您希望文件的第一部分位于地址 0x100000,则应在链接器脚本中使用等效的“-Ttext 0x1000”(如果使用链接器脚本,则不使用 -Ttext)并定义“图像库”至 0xFF000:

ld.exe -T linkerScript.ld --image-base 0xFF000 -o binary.tmp a.o main.o

“.text”部分的内存地址将为 0xFF000 + 0x1000 = 0x100000。

(“objcopy”生成的二进制文件的第一个字节将是第一个部分的第一个字节 - 表示内存地址 0x100000。)

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

MinGW的ld无法对非PE输出文件执行PE操作 的相关文章

  • C++ 中的 CPUID 实现

    我想知道这里是否有人有一些可以从任何托管 net 语言引用的 C CPUID 实现的好示例 另外 如果情况并非如此 我是否应该注意 X86 和 X64 之间的某些实现差异 我想使用 CPUID 来获取运行我的软件的机器上的信息 崩溃报告等
  • 模板基类 typedef 和函数有更好的 C++ 语法吗?

    我的代码可以在 VC9 Microsoft Visual C 2008 SP1 中正常编译 但不能在 GCC 4 2 中编译 在 Mac 上 如果这很重要的话 如果我堆积足够的限定符和关键字 我可以强制它在 GCC 中工作 但这似乎不对 这
  • 使用基类指针创建对象时缺少派生类析构函数

    在下面的代码示例中 未调用派生类析构函数 知道为什么吗 我有一个具有虚函数的基类 现在我使用基类指针来创建派生类的新对象 我的理解是 当派生类对象被销毁时 首先调用派生类的析构函数 然后调用基类 但是我只看到基类的析构函数被调用 有谁知道我
  • 安装 Pillow 错误:安装脚本退出并出现错误:命令“x86_64-linux-gnu-gcc”失败,退出状态为 1

    当我尝试安装 Pillow 2 5 3 时 我收到错误 命令 x86 64 linux gnu gcc 失败 退出状态为 1 这是所发生事件的完整日志 http pastebin com 5k2TsyJY 我需要这个库作为另一个 pytho
  • 什么时候汇编比C更快? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话 但却具有历史意义 目前不接受新的
  • Clang 使用 -nostdlib 生成崩溃代码

    我正在尝试为可执行文件设置自己的运行时环境 但无法使用 clang v3 4 1ubuntu1 目标 x86 64 pc linux gnu 来生成没有段错误的可执行文件 我已将问题简化为以下内容 如果我有一个文件 crt1 c 除了满足
  • 如何让c代码执行hex机器代码?

    我想要一个简单的 C 方法能够在 Linux 64 位机器上运行十六进制字节码 这是我的 C 程序 char code x48 x31 xc0 include
  • 未初始化成员的警告在 C++11 上消失

    我编译这个简单的程序 include
  • NASM 轮班操作员

    您将如何在寄存器上进行 NASM 中的位移位 我读了手册 它似乎只提到了这些操作员 gt gt lt lt 当我尝试使用它们时 NASM 抱怨移位运算符处理标量值 您能解释什么是标量值并举例说明如何使用 gt gt and lt lt 另外
  • 在linux x86平台上学习ARM所需的工具[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我有一个 x86 linux 机器 在阅读一些关于 ARM 的各种信息时 我很好奇 现在我想花一些时间学
  • 如何更改 Xcode 中的编译器

    我正在 Xcode 4 6 3 中编译 C 代码 但我不知道我正在使用哪个编译器 我需要使用 gcc 4 2 提前致谢 If you really需要更改为 gcc 您可以在构建设置中执行此操作
  • 使用 gcc 的中间 GIMPLE 格式

    根据本文 http en wikipedia org wiki Intermediate languagegcc 在生成代码之前使用多种中间格式 我读到 GIMPLE 格式使用三个地址代码 这似乎是最容易使用的中间语言 但我需要更多细节 因
  • 为什么 GCC 不将 a*a*a*a*a*a 优化为 (a*a*a)*(a*a*a)?

    我正在对科学应用程序进行一些数值优化 我注意到的一件事是 GCC 会优化调用pow a 2 通过将其编译成a a 但是调用pow a 6 没有优化 实际会调用库函数pow 这大大降低了性能 相比之下 英特尔 C 编译器 http en wi
  • C 中类似函数的宏定义

    我想定义一个像 MACRO 这样的函数 IE define foo x if x gt 32 x else 2 x endif 那是 if x gt 32 then foo x present x else foo x present 2
  • 使用 Easy 68K (68000) 组装范围内的随机数

    我正在使用 Easy 68K 模拟器创建一个简单的黑杰克游戏 需要使用随机数来分配牌 我的牌必须在 2 到 11 的范围内 我似乎每次都得到相同的数字 但它不在我预期的范围内 我的卡值需要以 D3 结束 因此我有以下随机数代码 CLR L
  • GCC 对潜在有效的代码抛出 init-list-lifetime 警告?

    我在 Debian不稳定的GCC 9 3 0上运行 我从事的一个项目最近发生了变化 引入了类似于下面的代码 include
  • 在64位操作系统上以32位模式和64位模式编译ioctl函数的执行有什么不同?

    我有 64 位 Enterprise SuSE 11 我有一个应用程序 它打开 HIDRAW 设备并在其上操作 ioctl 函数以从该设备获取原始信息 如下所示 struct hidraw devinfo devinfo int fd op
  • 使用 OpenMP 编译会导致内存泄漏

    根据 valgrind 的说法 使用 OpenMP 编译简单的 hello world 程序时可能会导致内存泄漏 这是没有意义的 因为 hello world 程序并没有有意使用任何 OpenMP 功能 假设下面的程序名为hi c并根据 g
  • 分析 ELF 部分和符号大小的工具

    我需要一种方法来分析 ARM 的 GCC 编译器的输出文件 我正在为裸机进行编译 并且我非常关心大小 我可以用arm none eabi objdump由交叉编译器提供 但如果存在用于此任务的工具 则解析输出并不是我渴望做的事情 您知道存在
  • “rep stos”x86 汇编指令序列有什么作用?

    我最近偶然发现了以下汇编指令序列 rep stos dword ptr edi For ecx重复 存储内容eax到哪里edi指向 递增或递减edi 取决于方向标志 每次 4 个字节 通常 这用于memset型操作 通常 该指令简单地写成r

随机推荐

  • 在 R 中提取名字

    假设我的数据框中有一个人名向量 names lt c Bernice Ingram Dianna Dean Philip Williamson Laurie Abbott Rochelle Price Arturo Fisher Enriq
  • C# 中的浮点数学一致吗?是真的吗?

    不 这不是另一个 为什么是 1 3 0 3 1 问题 我最近读了很多关于浮点的文章 具体来说 如何相同的计算可能会得到不同的结果在不同的架构或优化设置上 对于存储重播的视频游戏来说 这是一个问题点对点网络 https gamedev sta
  • GridView:单击按钮时获取行的数据键

    当我在具有 OnClick 事件的行中有一个按钮时 如何获取 GridView 行的 DataKeyName 的值 在按钮的 OnClick 事件中 我想获取按钮所在行的 DataKeyName 这可能吗
  • 按照发送的顺序显示 AJAX 响应,*不*使用排队或同步请求?

    我正在向远程服务器发送一堆 getJSON 请求 以获取图像 并且我想按照发送请求的顺序显示响应 图像 问题是 AJAX 是异步的 因此响应可以按照他们想要的任何顺序出现 通常都是混合的 我可以将它们排队或使它们同步 一次只发送一个请求 但
  • R 中的 print() 命令可以安静吗?

    R中的一些函数可以打印信息和返回值 打印可以静音吗 例如 print and return lt function print foo return bar returns gt print and return 1 foo 1 bar g
  • numpy.array.__iadd__ 和重复索引[重复]

    这个问题在这里已经有答案了 我有一个数组 A np array 0 0 0 和具有重复的索引列表 idx 0 0 1 1 2 2 我想使用上面的索引将另一个数组添加到 A 中 B np array 1 1 1 1 1 1 操作 A idx
  • aria 扩展的 html 属性

    我目前正在制作导航栏并遇到了aria expandedhtml 属性 我当然知道该元素用于让元素展开或折叠 我能找到的关于此的信息非常少W3C docs https www w3 org WAI GL wiki Using aria exp
  • 未找到“account_email_verification_sent”的反向操作。 “account_email_verification_sent”不是有效的视图函数或模式名称

    我正在尝试在我的项目中使用 allauth 和 rest auth 并尝试使用 allauth 中的内置函数进行电子邮件验证 但这就是我得到的 这是我的代码 设置 py ACCOUNT EMAIL VERIFICATION mandator
  • MVC 3 无法将字符串作为视图模型传递?

    我的模型传递到视图时遇到一个奇怪的问题 控制器 Authorize public ActionResult Sth return View Views Sth Sth cshtml abc View model string ViewBag
  • 如何在 vscode 中使用 jsdoc 正确获取包装函数中返回值的推断类型?

    这是一些代码 简化的 以更好地理解 发送请求的包装器 当请求发送和完成时 它会执行一些常见的操作 它返回请求的结果 处理程序 async function request handler common stuff try const res
  • 子图有相同的节点,如何使其唯一

    我通过 perl 脚本创建点文件 这是包含相同节点的子图 例如 subgraph aa gt bb gt cc subgraph dd gt bb gt ee 我知道这些子图使用相同的命名空间 所以我的结果输出很混乱 在每个子图中 我可以使
  • 在生成的 tokio 任务中使用 dyn 异步特征(带有 async-trait crate)

    我正在开发一个异步 Rust 应用程序 它利用tokio https crates io crates tokio 我还想将一些特征方法定义为async并选择了异步特征箱 https crates io crates async trait
  • 使用 Jasmine 测试 AngularJS 工厂函数

    我对此非常陌生 AngularJS 茉莉花 睾丸 我有这个代码 我简化了一点 只留下重要的部分 my module js angular module my module my data config controller my contr
  • 使用 jQuery 查找所选选项的名称

    我制作了一个 jquery ajax 函数来更新 courses 发送 fos 的 val 和 text 特别是所选的函数 如下所示 selling fos change function post ajax courses fos id
  • 是什么阻止我调整(缩小)我的 Windows 窗体对象的大小?

    我有一个 Windows 窗体对象 其中包含 3 个对象 一个树视图 一个富文本框和一个选项卡控件 它们没有停靠在窗口窗体中 但它们是锚定的 顶部 左侧 我已经编写了在调用 form resize 事件处理程序时调整它们大小的代码 但它似乎
  • 桥接表 - DAX 还是 M?

    我们应该使用 DAX 还是 M 构建桥接表 图片盗自here https stackoverflow com questions 53320431 power bi weighted average yield across 2 table
  • Magento SOAP v1 与 v2 性能对比

    我正在使用 VB NET 来处理 Magento API 我成功地使用了 SOAP v1 直到遇到需要关联数组的调用 经过一天左右的运气不佳后 我决定尝试 v2 它拥有我需要的所有对象 v2 可以工作 但是非常非常慢 要更新一个库存商品库存
  • SQL 查询以获取主管层次结构列表。员工-->主管-->主管

    我有两个表 员工 和 部门 该图像显示了每个员工的经理 我想编写一个 SQL 查询 为我提供所有主管 经理 经理的经理 的列表 我只想要一个列 在给定特定员工时显示主管列表 例如 如果我给员工 id 202 那么我应该收到 200 130
  • 如何查询位于不同数据库中的表?

    我最初的问题是关于是否将 ASPNETDB MDF 与应用程序数据库分开 或者将所有表合并到一个数据库中 检查之前的问题 答案 我了解到这取决于会员数据是否会在多个应用程序之间共享 现在 我的问题是这样的 如果我决定将 ASPNETDB M
  • MinGW的ld无法对非PE输出文件执行PE操作

    我知道还有一些其他类似的问题 无论是否是 StackOverflow 我为此进行了很多研究 但仍然没有找到单一的解决方案 我正在做一个操作系统作为一个业余项目 我一直在汇编中完成所有工作 但现在我想加入 C 代码 为了测试 我制作了这个汇编