简体   繁体   English

如何在Linux C内联汇编中使用宏

[英]How to use a macro in linux C inline assembly

I want to call an address that is determined by other configuration result. 我想调用由其他配置结果确定的地址。 And that call is in an inline assembly. 该调用是内联汇编中的。

Currently, it's like this and is manually modified: 当前,就像这样,并已手动对其进行了修改:

asm volatile ("call 0xc0200c20\n\t");

My question is can I write it like this? 我的问题是我可以这样写吗?

#define CALL_ADDR 0xC0200c20

asm volatile ("call CALL_ADDR\n\t");

Thanks! 谢谢!

Just ordinary string concatenation should do the trick, with two wrapper macros to create a stringified version of the value: 只需普通的字符串连接就可以解决问题,它使用两个包装宏来创建值的字符串化版本:

#define QUAUX(X) #X
#define QU(X) QUAUX(X)

asm volatile ("call " QU(CALL_ADDR) "\n\t");

Promoting my comment to an answer: 将我的评论提升为答案:

The P modifier for gcc's inline assembly operands stops the compiler from emitting 'constant-indicating prefixes' in the generated assembly code. gcc的内联汇编操作数的P修饰符可阻止编译器在生成的汇编代码中发出“常量指示前缀”。 See the linked reference for a more verbose explanation, quoting Linus. 请参阅链接的参考,以获得更详细的解释,并引用Linus。

If you've tried: 如果您尝试过:

#define CALL_ADDR 12345678
asm volatile("call %0\n\t" :: "i"(CALL_ADDR));

you noticed you get an error from the assembler, because the generated code says call $12345678 and that's not valid assembly syntax. 您注意到从汇编程序中收到错误,因为生成的代码显示call $12345678 ,这不是有效的汇编语法。 Using %P0 instead makes the compiler not emit the $ at the beginning, and it's fine. 相反,使用%P0可使编译器在开始时发出$ ,这很好。

There's no need to work with preprocessor string concatenation here - the disadvantage of that is, as you've found, that "nesting" (two levels of macros) is needed so that the CALL_ADDR is expanded before the concatenation is done. 此处不需要使用预处理程序字符串串联-缺点是,正如您所发现的,需要“嵌套”(两级宏),以便在完成串联之前扩展CALL_ADDR

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM