嵌入式用c语言还是汇编语言,什么时候使用c语言的易失性嵌入式汇编代码?

本文通过示例探讨了在C语言中使用汇编语句时,volatile关键字如何防止GCC优化掉未使用的输出参数。在没有assert或volatile的情况下,GCC可能会删除不必要的汇编代码。当添加volatile后,即使在优化模式下,汇编语句也不会被优化掉,展示了volatile在特定情况下的必要性。
摘要由CSDN通过智能技术生成

2-810-jpg_6-1080-0-0-1080.jpg

在阅读本文之前,请阅读gcc的相关文档,以确保您基本了解如何在C中使用汇编语言.

文档地址为:

以下示例说明了相关概念:

#include

#include

#include

void do_check(uint32_t dwSomeValue) {

uint32_t dwRes;

asm("bsfl %1,%0" : "=r"(dwRes) : "r"(dwSomeValue) : "cc");

assert(dwRes == 3);

}

int main(int argc, char *argv[]) { do_check(8); }

1d112269f5e0b12e13bc092443a02238.png

编译后,以汇编形式检查do_check方法:

$ gcc -O3 main.c && objdump --disassemble=do_check a.out

0000000000001190 :

1190: 0f bc ff bsf %edi,%edi

1193: 83 ff 03 cmp $0x3,%edi

1196: 75 01 jne 1199

1198: c3 retq

1199: 50 push %rax

119a: e8 c1 ff ff ff callq 1160

由于在assert宏中使用了asm语句中的输出参数dwRes,即使asm语句未指定volatile,do_check方法也会正常执行.

在删除assert方法之后,让我们看一下do_check汇编代码:

2-810-jpg_6-1080-0-0-1080.jpg

$ gcc -O3 -D NDEBUG main.c && objdump --disassemble=do_check a.out

0000000000001130 :

1130: c3 retq

从上面可以看出,因为我们在执行gcc时添加了-D NDEBUG参数,并定义了NDEBUG宏,因此上述assert宏最终将变为空指令.

也就是说c语言对应汇编语句,do_check方法中的任何地方都没有在asm语句中使用输出参数dwRes,因此gcc会在优化的代码中删除asm语句,因此上述do_check方法最终成为空方法.

然后将上面的asm语句添加到volatile中,然后重试:

7-810-jpg_6-1080-0-0-1080.jpg

void do_check(uint32_t dwSomeValue) {

uint32_t dwRes;

asm volatile("bsfl %1,%0" : "=r"(dwRes) : "r"(dwSomeValue) : "cc");

assert(dwRes == 3);

}

编译后,以汇编形式检查do_check方法:

$ gcc -O3 -D NDEBUG main.c && objdump --disassemble=do_check a.out

0000000000001130 :

1130: 0f bc ff bsf %edi,%edi

1133: c3 retq

从上面可以看到,这一次即使指定了-D NDEBUG参数,assert宏也变成了no-op,导致在do_check方法中的任何地方都没有使用dwRes变量,但是由于volatile的存在c语言对应汇编语句,仍然对asm语句进行了优化.

t01e49dbbad45ed1b.jpg

通过上面的示例,我们可以看到volatile如何阻止gcc优化代码,但是在上面的示例中,该优化是正确的优化,因此不应添加volatile.

如果还有其他asm语句,尽管未使用其输出参数,但不应对其进行优化. 此时,应使用volatile.

希望对您有帮助.

结束.

本文来自电脑杂谈,转载请注明本文网址:

http://www.pc-fly.com/a/jisuanjixue/article-200715-1.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值