找回密码
 注册
搜索
查看: 1186|回复: 4

[讨论] 一个诡异的难题,求教!!

[复制链接]
发表于 2010-9-8 16:13:14 | 显示全部楼层 |阅读模式
stmia r0!,{r1,r2}   //r0值为0x4027e4c,r1和r2值都为0
bne addr_right      //这一句为伪代码
assert                  //这一句为伪代码


执行第一句前r0值为0x4027e4c,可是执行完第一句以后就assert了。
理论上,执行第一句后r0的值应该加8,即0x4027E54,应该不会影响z标志位,那么为什么没有跳转到addr_right处继续执行呢?
(补充一点,当前工作在thumb状态,而且加入了-zo编译选项)
 楼主| 发表于 2010-9-9 19:03:58 | 显示全部楼层
syw501说的太对了,后来才发现问题是前面代码的问题,但似乎又是无解的问题。c代码是这样的:(以下都是简写)
两个数据结构
typedef struct
{
short mm1;
short mm2;
short mm3;
short mm4;
}struct2;

typedef struct
{
----
----
struct2 m1;
struct2 m2;
----
----
}struct1;


struct1 g_test;

在代码中要对m1和m2清零:
if(0 == &(g_test.m1))
{
    assert;
}
else
{
    memset(&(g_test.m1), 0, 8);
}
if(0 == &(g_test.m2))
{
    assert;
}
else
{
    memset(&(g_test.m2), 0, 8);
}
于是出问题了,因为arm的汇编是这样的:
beq assert  //if(0 == &(g_test.m1))
mov r1,0
mov r2,0
stmia r0!,{r1,r2}   //为g_test.m1清零
beq assert  //if(0 == &(g_test.m2))
stmia r0!,{r1,r2}   //为g_test.m2清零

倒数第二句的beq assert导致了最终的assert。
问题在于mov r2,0之后Z标志位就被置了。这以前已经检查没有问题了。
如果不加zo选项,前面的汇编就不会是这样,取g_test.m2的地址的时候不会利用m1进行清零后自动加8的地址,所以就不会有问题。

现在的问题就是
1.mov r2,0在thumb指令下更改了标志位,既然这样,编译器就不应该在后面直接判断标志位。这只能说编译器优化的问题。
2.目前汇编就是这样的情况下,怎么解决这个问题?
点评回复

使用道具 举报

发表于 2010-9-9 12:54:28 | 显示全部楼层
检查前面的汇编
点评回复

使用道具 举报

 楼主| 发表于 2010-9-16 15:05:14 | 显示全部楼层
up,继续求解
点评回复

使用道具 举报

 楼主| 发表于 2010-9-13 22:20:31 | 显示全部楼层
up
继续寻解
点评回复

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies

本版积分规则

Archiver|手机版|小黑屋|52RD我爱研发网 ( 沪ICP备2022007804号-2 )

GMT+8, 2024-10-9 02:25 , Processed in 0.046742 second(s), 16 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表