我有一个涉及模拟的项目(如果你查看我的帖子历史,你会看到我到底有多远!)我想要做伪二进制-translation使用C并与优化器和/或编译器一起使用C代码,将我的switch语句内容编译为单个汇编指令,主要用于非常标准的指令,例如mov
s,add
,{ {1}}和其他简单的位操作和算术指令。我希望同时为ARM和x86-64执行此操作,尽可能少地在两个程序集中编写。
如果我描述的东西不存在,那么我想知道是否有某种"汇编语言"我可以用来编写我的代码,然后将该程序集编译为x86-64和ARM。
答案 0 :(得分:3)
如果要在运行时发出机器代码,则需要一些Just In Time translation库。您可以考虑GNU lightning,libjit,LLVM,GCCJIT,asmjit ......
你也可以(在Linux上)在某个文件中生成一些C代码,将该文件的汇编分成一个共享对象,然后dlopen(3) - 那个.so
插件......
正如我评论的那样:跨平台程序集不存在且不存在(因为系统具有不同的instruction sets和ABI约定):考虑生成C代码,或者可能LLVM IR代码
如果您正在编写一些interpreter(其中包含许多emulators),请同时考虑threaded code种技术和bytecode代。
答案 1 :(得分:3)
要清楚地回答这一部分:
...然后我想知道是否有某种"汇编语言"我能 用来编写我的代码,然后将该程序集编译成x86-64和 ARM。
这正是LLVM IR所针对的目标。
LLVM表示旨在轻量级和低级别 同时具有表现力,类型和可扩展性。它旨在 通过处于足够低的水平,成为各种“普遍的IR” 高层次的想法可以干净地映射到它(类似于如何 微处理器是“通用IR”,允许许多源语言 要映射到他们)。
您可以代表此C函数
int mul_add(int x, int y, int z) {
return x * y + z;
}
使用此LLVM IR
define i32 @mul_add(i32 %x, i32 %y, i32 %z) {
entry:
%tmp = mul i32 %x, %y
%tmp2 = add i32 %tmp, %z
ret i32 %tmp2
}
答案 2 :(得分:3)
以尖锐的方式说出,#34;汇编语言"你正在谈论的是... C.
这是因为即使在不同的平台上,很多C表达式也只能直接映射到单个汇编指令。以下是部分假设,但它显示了某些C表达式可能在x86,ARM或SPARC上评估的一些指令(选择那三个因为那些是我最熟悉的):
C code x86 asm ARM asm SPARC asm
{ enter push lr save %fp, ..., %sp
} leave pop pc restore
a += b; add %ebx, %eax add R0, R1 add %l0, %l1, %l0
a = b + c; lea (%ebx, %ecx), %eax add R0, R1, R2 add %l2, %l1, %l0
a = 0; xor %eax, %eax mov R0, #0 clr %l0
a++; inc %eax add R0, #1 inc %l0
a--; dec %eax sub R0, #1 dec %l0
*ptr++; inc (%eax) - -
a = ~b; mov %ebx, %eax; not %eax mvn R0, R1 not %l1, %l0
ptr = &a; lea a, %eax ldr R0, =a set a, %l0
a = b[c]; mov (%ebx, %ecx), %eax ldr R0, [R1+R2] ld [%l1+%l2], %l0
(void)func(); call func blx func call func
if (a) test %eax, %eax; jnz tst R0, R0; bnz tst %l0; bnz
当然,并非您可以编写为一行C代码的所有内容都将转换为单个汇编指令。如果某些多期操作可以“平坦化”,它也很大程度上取决于指令集。单个多操作数汇编指令或需要一个更原始的序列"指令。
很长一段时间以来,C编译器已经完成了'#34;中间表示"在最终转换为组装之前;这个步骤类似于现在用硬件通过x86 CPU到#34;编译"将x86组装成芯片的实际执行单元将处理的低级微操作。对LLVM IR进行编码/记录的中间层也不是那么新......因为例如Java Bytecode或Forth在概念上符合该架构。我去C ...并查看装配输出。它不可能像现在这样紧凑,并且在相应的"化合物"操作是可用的,不可能比LLVM IR更紧凑(例如,在带有融合乘法加法的cpu上,auselen给出的示例将从LLVM IR中的三个指令开始下载。)