gcc - gcc ARM 产生不正确的代码 - 如何更正
问题描述
用于 STM32F407 微的 gcc ARM
以下函数用作 FreeRtosTCP 中的健全性检查
UBaseType_t bIsValidNetworkDescriptor( const NetworkBufferDescriptor_t * pxDesc )
{
uint32_t offset = ( uint32_t ) ( ((const char *)pxDesc) - ((const char *)xNetworkBuffers) );
if( ( offset >= (uint32_t)(sizeof( xNetworkBuffers )) ) || ( ( offset % sizeof( xNetworkBuffers[0] ) ) != 0 ) )
return pdFALSE;
return (UBaseType_t) (pxDesc - xNetworkBuffers) + 1;
}
有问题的行是---> offset >= (uint32_t)(sizeof( xNetworkBuffers ))
gcc 在 cmp 而不是 bhs 之后生成 bhi 指令。
如果尝试如上面的代码所示同时转换两者,但似乎没有任何东西可以使用 bhs 指令。
任何帮助表示赞赏。
谢谢。
乔
解决方案
知道 xNetworkBuffers 数组编译器的确切大小可以简单地对其进行优化。出于好奇,我试了一下。以下是稍加修改的代码以及 asm 输出和解释:
#include <stdint.h>
typedef struct abc {
char data[10];
}NetworkBufferDescriptor_t;
NetworkBufferDescriptor_t xNetworkBuffers[5];
int bIsValidNetworkDescriptor( const NetworkBufferDescriptor_t * pxDesc )
{
uint32_t offset = ( uint32_t ) ( ((const char *)pxDesc) - ((const char *)xNetworkBuffers) );
if( ( offset >= (uint32_t)(sizeof( xNetworkBuffers )) ) || ( ( offset % sizeof( xNetworkBuffers[0] ) ) != 0 ) )
return 0;
return (int) (pxDesc - xNetworkBuffers) + 1;
}
asm 输出为:
bIsValidNetworkDescriptor:
@ Function supports interworking.
@ args = 0, pretend = 0, frame = 16
@ frame_needed = 1, uses_anonymous_args = 0
@ link register save eliminated.
str fp, [sp, #-4]!
add fp, sp, #0
sub sp, sp, #20
str r0, [fp, #-16]
ldr r3, [fp, #-16]
ldr r2, .L5
sub r3, r3, r2 str r3, [fp, #-8] ldr r3, [fp, #-8] cmp r3, #49 bhi .L2
ldr r1, [fp, #-8]
ldr r3, .L5+4
umull r2, r3, r1, r3
lsr r2, r3, #3
mov r3, r2
lsl r3, r3, #2
add r3, r3, r2
lsl r3, r3, #1
sub r2, r1, r3
cmp r2, #0
beq .L3
.L2:
mov r3, #0
b .L4
.L3:
ldr r3, [fp, #-16]
ldr r2, .L5
sub r3, r3, r2
asr r2, r3, #1
mov r3, r2
lsl r3, r3, #1
add r3, r3, r2
lsl r1, r3, #4
add r3, r3, r1
lsl r1, r3, #8
add r3, r3, r1
lsl r1, r3, #16
add r3, r3, r1
lsl r3, r3, #2
add r3, r3, r2
add r3, r3, #1
.L4:
mov r0, r3
add sp, fp, #0
@ sp needed
ldr fp, [sp], #4
bx lr
.L6:
.align 2
.L5:
在引用 asm 代码的块中,您可以看到它与 49 而不是 50(这是 xNetworkBuffers 的实际大小)进行比较,所以我得到的结论是
offset >= (uint32_t)(sizeof( xNetworkBuffers ))
也等于
offset > (uint32_t)(sizeof( xNetworkBuffers ) - 1) )
在这种情况下,编译器可以使用 BHI 产生相同的结果
推荐阅读
- angularjs - 如何从不同的页面角度检索数据
- ios - 是否有可能,以及如何在使用 frida gadget 重新打包 iOS 应用程序时将键值对添加到新的权利文件中?
- c# - 日期不接受空值
- r - 复制 R 食谱中的示例时 scale_colour_discrete 不起作用
- php - VS 代码调试器 - Felix Becker - 调试器没有遇到任何问题
- reactjs - 当我在 CMD 窗口中编写 npx create-react-app-my-app 时出现错误。我已经安装了 Node.js:C:\Users\dev>node --version v15.4.0****
- ionic-framework - 如何在 android studio 模拟器上运行基于 ionic 开发的应用程序
- lua - 罗技 G-Hub 的最新更新中缺少数学库
- javascript - 无法使用vue和moment将参数传递给茉莉花中的按钮方法
- reactjs - 在 React 中使用 this.setState 时遇到“错误:Material-UI:capitalize(string) 需要一个字符串参数”