【发布时间】:2013-03-06 03:33:14
【问题描述】:
有各种开源汇编器,例如gas、nasm 和yasm。它们有不同的 pseudo-ops 和 macro 语法。对于许多开源项目,汇编程序经过预处理以替换常量和平台条件。
假设您可以使用所有当前的attributes 和#pragmas,gcc 创建汇编程序会有什么限制,不包括翻译性能(编译/汇编到二进制时间)?
我不是在谈论inline-assembly。
#define MOV(RA,RB) (OXFEB10000UL | RA << 16 | RB)
#define ADD(RA,RB) (OXFEB20000UL | RA << 16 | RB)
#define RET (OXFEB7ABCDUL)
unsigned long add4[] __attribute(section(".text")) =
{
ADD(R0,R1),
ADD(R2,R3),
MOV(R1,R2),
ADD(R0,R1),
RET()
};
我相信使用指针算法可以模拟.和其他labels。也许这是一个XY problem;我试图理解为什么有这么多汇编程序。似乎一切都可以由预处理器完成,而汇编器确实是程序员的偏好;或者我缺少技术限制。
我想这可能与“使用汇编程序可以做的事情,而 shell code 无法做到的事情”有关。
编辑:我已将它从 C 重新标记为 compiler。我对汇编程序的技术细节感兴趣。它是简单的1-1 翻译和发射重定位(编译器会这样做)还是还有更多?正如我上面所概述的那样,我并不是要人们编写汇编程序。我试图了解汇编程序在做什么。我不相信有适合装配工的龙书。当然,预处理器不能自己创建binary,需要额外的机器;它只翻译文本。
【问题讨论】:
-
我认为这不适用于 x86。为特定指令选择最佳编码并非易事,对齐会很棘手,据我所知,优化分支大小是完全不可能的。在任何情况下,您都会在螺丝上使用锤子。
-
@Harold:你能详细说明它是如何不起作用的吗?对于 x86,它会复杂得多,并且需要
byte对齐。 x86 汇编器是否必须在内存中保留较大的基本块才能生成操作码? -
@Bill - x86 有可变长度指令,助记符和操作码之间没有 1-1 的关系。例如,一个“简单”的 MOV 有 20 多种不同的变体,例如
MOV AX,1与MOV other_reg,1不同。 -
@BillPringlemeir 否,但它最终会在内存中保留大块,以满足对齐约束,同时优化分支大小。它仅需要字节对齐,但它确实喜欢某些分支目标的 16 对齐。
-
您可能会发现这本古代汇编器手册很有用。 bitsavers.org/pdf/dec/pdp1/PDP-1_Macro.pdf
标签: gas nasm yasm inline-assembly c gcc assembly compiler-construction