使用`GCCs`预处理器作为汇编程序

时间:2013-03-17 20:40:02

标签: c gcc assembly compiler-construction

有各种开源汇编程序,例如。它们具有不同的pseudo-opsmacro语法。对于许多开源项目,汇编程序经过预处理以替换常量和平台条件。

gcc假设您可以使用所有当前attributes#pragmas,但不包括翻译性能(编译/汇编到二进制时间),会有什么限制来创建汇编程序?

我不是在谈论

 #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 重新标记为编译器。我对汇编程序的技术细节感兴趣。它只是一个1-1翻译和发布重定位(作为编译器将)还是更多?我不是指人们编写汇编程序,如上所述。我试图了解装配工正在做什么。我不相信装配工有龙书。当然,预处理器本身不能创建binary并且需要额外的机制;它只翻译文本。

2 个答案:

答案 0 :(得分:3)

  

gcc有什么限制来创建汇编程序[...]?

很多。我们使用汇编程序进行汇编和C预处理程序进行预处理是有原因的。

首先,正如您刚刚自己展示的那样,您无法使用英特尔或AT&amp; T风格的常规汇编语法。你必须使用那些丑陋的括号。

其次,你所谈论的那些__attribute__指令与预处理器无关,它甚至不能识别它们。它们是编译器的提示,编译器将依次生成由这些属性(或不是)引导的汇编代码。

  

也许这是一个XY问题

这是肯定的。

  

我试图理解为什么会有这么多的汇编程序。

出于同样的原因,有各种类型的编程语言,编译器,汽车和服装:一种工具不适合每个人的需要。人们不同,他们使用他们的工具链做不同的事情,他们发现一个比另一个更容易使用(如果它不需要AT&amp; T语法,我个人会使用GNU汇编程序,我不能支持)等等。

答案 1 :(得分:3)

我认为XY Problem是错误的描述。问题是评估概念B 需要更多“概念A 。”


概念A:什么是汇编程序?

请参阅:Assemblers and Loader David Solomon 。 [一些智慧的珍珠,一些古老的琐事]

  

我很快发现这个领域缺乏文献资料。与存在大量文献的编纂者形成鲜明对比的是,关于装配工和装载机的编写很少。

汇编程序包含,

  • A Symbol table以便于通过某种对象格式进行链接。
  • LexerParser用于将文本转换为数据结构或直接转换为机器代码。
  • Does 2 passes用于最有效的分支和子程序调用。
  • 操作码表。

汇编程序通常是1-1翻译。但是,通常会存在分支和调用的几种变体;通常称为 long short 版本。使用的操作码取决于到目的地的距离;需要一个两遍编译器来优化前向分支。Harold

提及

概念B:使用'C'预处理器作为汇编程序。

最佳'C'预处理器可以模拟的是1遍汇编程序。可以像这样编码一大类CPU /指令;虽然宏可能很麻烦。没有列表 xrefs ,但大多数人都不会错过这些功能。而且,由于预处理器的限制,语法将是奇数。处理地址修复很困难,因为标签要么通过使用指针重新使用'C'符号表,要么使用手动编码#define来标记偏移。这将此方法限制为除basic block之外的任何内容。

大型汇编程序例程

YUV / RGB变换或MP3解码等大型汇编程序很难以这种方式使用。

多拱代码

多种架构代码非常常见。例如,ARM wifi芯片可能将其代码嵌入Linux内核中作为固件。这种技术可能在这里很有用。但是,对不同的体系结构使用单独的编译器/汇编器,然后使用objcopy来嵌入它们会更加明智。

自我修改代码

这可能是最有用的。实际上,许多工具(如链接器和加载器)具有高级功能,可在运行时修补代码。它还可以用于在运行时有条件地更改例程;函数指针几乎同样快速且易于理解,更不用说缓存一致性问题了。

另见:Gold Blog Ian Lance Taylor 。 [虽然他使用<templates>]