如何告诉 GCC 在特定位置放置内联汇编指令?
How to tell GCC to place an inline assembly instruction at a specific position?
我正在为基于 ORPSoC 的处理器架构开发引导加载程序。为了执行一个程序,引导加载程序将其加载到内存中,然后跳转到该程序的开头。
现在我需要在跳转的延迟槽中插入自定义指令l.cust1
。该指令由处理器执行并激活后续指令的解密。这就是为什么它 必须 放在延迟槽中的原因。再晚一点,程序就无法执行了,因为它的指令是加密的。同样,如果过早激活解密,bootloader会因为没有加密而崩溃。
我现在想知道是否可以告诉 GCC 在何处放置 l.cust1
指令。目前我必须相应地手动修改引导加载程序二进制文件。
在引导加载程序的 C 源代码中插入内联汇编 __asm__("l.cust1\n\t");
会导致在相关跳转之前的某处添加指令:
1fc2e10: 9c 21 01 b4 l.addi r1,r1,436
1fc2e14: 70 00 00 00 l.cust1 # switching on decryption
1fc2e18: 18 40 01 ff l.movhi r2,0x1ff
1fc2e1c: 9c 72 ff ff l.addi r3,r18,-1
1fc2e20: a8 42 7c 94 l.ori r2,r2,0x7c94
1fc2e24: 9c 90 00 04 l.addi r4,r16,4
1fc2e28: 85 62 00 60 l.lwz r11,96(r2)
1fc2e2c: 48 00 58 00 l.jalr r11
1fc2e30: 9d c0 00 00 l.addi r14,r0,0
但是,我需要它位于跳跃的延迟槽中:
1fc2e10: 9c 21 01 b4 l.addi r1,r1,436
1fc2e14: 9d c0 00 00 l.addi r14,r0,0
1fc2e18: 18 40 01 ff l.movhi r2,0x1ff
1fc2e1c: 9c 72 ff ff l.addi r3,r18,-1
1fc2e20: a8 42 7c 94 l.ori r2,r2,0x7c94
1fc2e24: 9c 90 00 04 l.addi r4,r16,4
1fc2e28: 85 62 00 60 l.lwz r11,96(r2)
1fc2e2c: 48 00 58 00 l.jalr r11
1fc2e30: 70 00 00 00 l.cust1 # switching on decryption
您需要使用 asm volatile
和对您希望内联汇编继续进行的代码的人为依赖。示例取自 gcc documentation is below:
asm volatile ("mtfsf 255,%1" : "=X"(sum): "f"(fpenv));
sum = x + y;
根据文档 volatile
单独是不够的。换句话说,编译器仍然可能改变以下代码的顺序:
asm volatile("mtfsf 255,%0" : : "f" (fpenv));
sum = x + y;
通过添加依赖项,您可以确保内联程序集的放置。在第一个代码片段中,通过添加对 sum
的依赖,可以确保编译器不会对代码重新排序,因为它认为它会由于依赖而生成不同的结果。您可以在 "C code optimization" 部分的 this webpage 上找到另一个例子。
将 l.cust1
放在与跳转相同的内联汇编程序语句中,必须声明 volatile
因为它有副作用,并且在 clobber 列表中有 "memory"
因为它取决于关于记忆的内容。
我正在为基于 ORPSoC 的处理器架构开发引导加载程序。为了执行一个程序,引导加载程序将其加载到内存中,然后跳转到该程序的开头。
现在我需要在跳转的延迟槽中插入自定义指令l.cust1
。该指令由处理器执行并激活后续指令的解密。这就是为什么它 必须 放在延迟槽中的原因。再晚一点,程序就无法执行了,因为它的指令是加密的。同样,如果过早激活解密,bootloader会因为没有加密而崩溃。
我现在想知道是否可以告诉 GCC 在何处放置 l.cust1
指令。目前我必须相应地手动修改引导加载程序二进制文件。
在引导加载程序的 C 源代码中插入内联汇编 __asm__("l.cust1\n\t");
会导致在相关跳转之前的某处添加指令:
1fc2e10: 9c 21 01 b4 l.addi r1,r1,436
1fc2e14: 70 00 00 00 l.cust1 # switching on decryption
1fc2e18: 18 40 01 ff l.movhi r2,0x1ff
1fc2e1c: 9c 72 ff ff l.addi r3,r18,-1
1fc2e20: a8 42 7c 94 l.ori r2,r2,0x7c94
1fc2e24: 9c 90 00 04 l.addi r4,r16,4
1fc2e28: 85 62 00 60 l.lwz r11,96(r2)
1fc2e2c: 48 00 58 00 l.jalr r11
1fc2e30: 9d c0 00 00 l.addi r14,r0,0
但是,我需要它位于跳跃的延迟槽中:
1fc2e10: 9c 21 01 b4 l.addi r1,r1,436
1fc2e14: 9d c0 00 00 l.addi r14,r0,0
1fc2e18: 18 40 01 ff l.movhi r2,0x1ff
1fc2e1c: 9c 72 ff ff l.addi r3,r18,-1
1fc2e20: a8 42 7c 94 l.ori r2,r2,0x7c94
1fc2e24: 9c 90 00 04 l.addi r4,r16,4
1fc2e28: 85 62 00 60 l.lwz r11,96(r2)
1fc2e2c: 48 00 58 00 l.jalr r11
1fc2e30: 70 00 00 00 l.cust1 # switching on decryption
您需要使用 asm volatile
和对您希望内联汇编继续进行的代码的人为依赖。示例取自 gcc documentation is below:
asm volatile ("mtfsf 255,%1" : "=X"(sum): "f"(fpenv));
sum = x + y;
根据文档 volatile
单独是不够的。换句话说,编译器仍然可能改变以下代码的顺序:
asm volatile("mtfsf 255,%0" : : "f" (fpenv));
sum = x + y;
通过添加依赖项,您可以确保内联程序集的放置。在第一个代码片段中,通过添加对 sum
的依赖,可以确保编译器不会对代码重新排序,因为它认为它会由于依赖而生成不同的结果。您可以在 "C code optimization" 部分的 this webpage 上找到另一个例子。
将 l.cust1
放在与跳转相同的内联汇编程序语句中,必须声明 volatile
因为它有副作用,并且在 clobber 列表中有 "memory"
因为它取决于关于记忆的内容。