下面的C代码:
s32 load_string(char* string_new, char const* string_orign)
{
StrEntry *entry = search_str_entry(string_orign);
u8 buff_b[32];
u16 buff_u[32];
s32 read_size = 0;
void *str_file = 0;
if (entry != 0){
cmemclr(buff_b, 32);
cmemclr(buff_u, 64);
sprintf(&buff_b[0], "c:/data/%03d.str", entry->fid);
c2w(&buff_u[0], &buff_b[0], 32);
if (TryOpenFile(&str_file, buff_u, OPEN_MODE_READ) == 0){
cmemclr(string_new, 256);
TryReadFile(&read_size, str_file, entry->offset, string_new, entry->size);
CloseFile(str_file);
return (s32)entry->size;
}
}
return 0;
}
该功能的反汇编:
003464ac <load_string>:
3464ac: e92d4010 push {r4, lr}
3464b0: e1a00001 mov r0, r1
3464b4: ebffffda bl 346424 <search_str_entry>
3464b8: e3500000 cmp r0, #0
3464bc: 08bd8010 popeq {r4, pc}
3464c0: eafffffe b 3464c0 <load_string+0x14>
我们可以看到if部分变成了无限循环,为什么?
我使用-Os优化选项来编译此代码。 gcc版本是
gcc版本8.1.0(devkitARM版本49)。
编辑:
cmemclr是一个简单的内联函数:
static inline void cmemclr(void *buf, u32 size)
{
u8 *dst = (u8*)buf;
while(--size >= 0){
dst[size] = 0;
}
}
答案 0 :(得分:6)
cmemclr
有缺陷。每次对问题进行编辑时,cmemclr
为:
static inline void cmemclr(void *buf, u32 size)
{
u8 *dst = (u8*)buf;
while(--size >= 0){
dst[size] = 0;
}
}
由于size
的类型为u32
(可能是无符号的),因此--size >= 0
始终为true。代码进入无限循环。
一种可能是您显示的汇编代码不完整,并且当前显示为b 3464c0
的汇编代码将在以后解析到另一个地址。
假设程序集正确,并且不是等待进一步链接解析的不完整占位符,则编译器已将if
语句中的代码优化为无限循环,或者是因为该语句中存在未定义的行为(因此,无限循环是允许的行为),或者因为语句中的某些内容执行了无限循环。
由于您尚未提供if
语句中使用的例程或宏的实现或规格,因此无法进行进一步的诊断。