奇怪的问题:一个函数被调用两次,输入同样的参数值,结果确不一样?

dreamuser 2009-01-03 11:41:23
此函数如下:
static __inline__ unsigned int Func(unsigned int input)
{
unsigned char *pval = (unsigned char *)&input;
unsigned char temp1, temp2;

temp1 = (unsigned int)(pval[0] ^ pval[1]);
temp2 = (unsigned int)(pval[2] ^ pval[3]);
return( ((temp1 << 4) ^ temp2) & 4095);
}
运行环境:
OS:vxworks
gcc编译器,使用makefile编译
实参传进来就是一个临时变量,与多线程同步没有关系。

现象:
1)当执行设置操作时,会调用此函数,输入参数值后得到是错误的结果(返回值是错误的)。
2)当执行查询操作时,会调用此函数,输入参数值后得到是正确的结果(返回值是正确的)。

3)当把函数定义中的"__inline__ "去掉或是函数定义中改为
static __inline__ unsigned int Func(volatile unsigned int input)
结果是对的。

4)当函数改为
static __inline__ unsigned int Func(unsigned int input)
{
unsigned char *pval = (unsigned char *)&input;
unsigned char temp1, temp2;
printf("");

temp1 = (unsigned int)(pval[0] ^ pval[1]);
temp2 = (unsigned int)(pval[2] ^ pval[3]);
return( ((temp1 << 4) ^ temp2) & 4095);
}

时是对的


5)但改为
static __inline__ unsigned int Func(unsigned int input)
{
unsigned char *pval = (unsigned char *)&input;
unsigned char temp1, temp2;

temp1 = (unsigned int)(pval[0] ^ pval[1]);
temp2 = (unsigned int)(pval[2] ^ pval[3]);
printf("");
return( ((temp1 << 4) ^ temp2) & 4095);
}
函数却返回错误的结果。

请大虾们不吝指教!!
Thank you!!
...全文
1749 26 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
kuku025 2009-06-17
  • 打赏
  • 举报
回复
GCC优化inline函数时的一些问题

1.强制类型转换无法被正确处理:
当使用-O2或-O3选项对代码进行优化时,gcc不能正确处理inline函数中的类似*(int *)&a/*a为float型*/这样的强制类型转换,-O1及不优化时可正确识别该转换。目前的解决方法是用如下代码代替上述强制类型转换:
...
union{
float s;
int i;
} s2i;
s2i.s = a;/*a is a float*/
printf("%d\n", s2i.i);/*将单精度浮点数a转化为整形且不改变a所在内存处的值,及实现*(int *)&a转换*/
...

2.优化时无法识别inline函数中的ASM汇编
当GCC尝试内联一个函数时,如果该函数中存在内联汇编,则该汇编语句块可能被丢弃;
...
__inline__ __attribute__((always_inline)) int Increment(int volatile *add, int inc)
{
int res;
__asm__
(
"lock \n\t"
"xaddl %0,(%1)\n\t"
:"=r"(res)
:"r"(add),"0"(inc)
:"memory"
);
return res;
}

int main(int argc, char *argv[])
{
int num = 1;
Increment(&num, 1);
printf("num = %d", num);
return 0;
}
上述代码中,由于GCC未发现输入参数add与Increment中汇编代码的关系,在inline时将嵌入式汇编代码丢弃,结果无论是否优化,由于强制内联,num的输出值都为1,不为2;
解决方法,一是定义一个整形变脸,用它获取并输出Increment的返回值(int dummy = Increment(&num, 1); printf("%d\n", dummy);),编译器会发现函数内局部变量与汇编代码的关系并在内联时保留汇编代码。
二是,在__asm__后加后缀__volatile__使GCC不对汇编代码做优化,从而避免优化错误。
FoxOnWeb 2009-01-24
  • 打赏
  • 举报
回复
把一个整数转成指针?
dreamuser 2009-01-24
  • 打赏
  • 举报
回复
上面贴子函数static __inline__ unsigned int Func(volatile unsigned int input); 中
idx1是temp1, idx2是temp2。不好意思没写的统一.
dreamuser 2009-01-24
  • 打赏
  • 举报
回复
最近看了一下MIPS的汇编,从上面三个函数汇编码来看,好像引起原因地方是:

只有__inline__的函数static __inline__ unsigned int Func(unsigned int input) 红色部分,偏移量是64.
25c: 8e240020 lw $a0,32($s1)
260: 27a30040 addiu $v1,$sp,64
264: 90650001 lbu $a1,1($v1) //pval[1]
268: afa40040 sw $a0,64($sp)
26c: 93b00040 lbu $s0,64($sp)

270: 90640003 lbu $a0,3($v1) //pval[3]
274: 90620002 lbu $v0,2($v1) //pval[2]
278: 02058026 xor $s0,$s0,$a1 //pval[0] ^ pval[1]
27c: 00108100 sll $s0,$s0,0x4 //temp1 << 4
280: 00441026 xor $v0,$v0,$a0 //pval[2] ^ pval[3]
284: 02028026 xor $s0,$s0,$v0 //(temp1 << 4) ^ temp2
288: 0200282d move $a1,$s0
28c: 3c040000 lui $a0,0x0
290: 64840050 daddiu $a0,$a0,80



而加上volatile的偏移量是32,函数static __inline__ unsigned int Func(volatile unsigned int input);

25c: 8e230020 lw $v1,32($s1)
260: 3c040000 lui $a0,0x0
264: 64840050 daddiu $a0,$a0,80
268: afa30020 sw $v1,32($sp)
26c: 93a30021 lbu $v1,33($sp) //pval[1]
270: 93b00020 lbu $s0,32($sp) //pval[0]

274: 93a50023 lbu $a1,35($sp) //pval[3]
278: 93a20022 lbu $v0,34($sp) //pval[2]
27c: 02038026 xor $s0,$s0,$v1 //pval[0] ^ pval[1]
280: 00108100 sll $s0,$s0,0x4 //idx1 << 4
284: 00451026 xor $v0,$v0,$a1 //pval[2] ^ pval[3]
288: 02028026 xor $s0,$s0,$v0 //(idx1 << 4) ^ idx2
28c: 0200282d move $a1,$s0
没有加__inline__和volatile也是32.

刚了解一点MIPS的汇编,为什么加上volatile后编移量改为32了,而不加是64.
补充:
1.环境的支持64位的MIPS CPU
2.Makefile编译选项:
-G
-mno-branch-likely
-mips3
-EL
-ansi
-fno-builtin
-DMIPSEL
-w
-Wall
-Wno-unused
-Wno-comment
-Werror
-g
-gstabs
-O2
-EL
-N
-r
-ansi
-fno-builtin
-Wp
-MMD

Cpp权哥 2009-01-07
  • 打赏
  • 举报
回复
可能是因为inline所以这个函数不再是一个真正的函数了,所以在多线程的时候出现了问题。
微笑的撒旦 2009-01-07
  • 打赏
  • 举报
回复
应该是优化的问题。
因为内联函数的参数是unsigned int型而不是指针型,所以没有加volatile的时候,虽然是取址操作,估计也直接优化掉了。MPIS的汇编不认识:)。
如果不是内联函数,input就是一个真的参数,需要等待赋值所以它的值每次都是更新过的。

4中的printf的位置在input被引用之前,也许会阻止该优化;5是在引用之后,所以没影响了。

可以用5的方式把input值打印出来看看是不是一样。
dreamuser 2009-01-06
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 yutaooo 的回复:]

是的,的确是对input的值进行计算,我没仔细考虑。

上面出现3个版本的Func,整理如下,不知道是否如此 :(


C/C++ code

static __inline__ unsigned int Func(unsigned int input); // v1 错误
static __inline__ unsigned int Func(volatile unsigned int input); // v2 正确
static unsigned int Func(unsigned int input); // v3 正确





没有学过MIPS汇编,不过比较了一下。v1版264开始的代码,先从栈…
[/Quote]

v1是错误的, v2 或v3的正确的。其实已经在问题的描述时,就已经指出来了。请参考最顶楼问题描述。



yutaooo 2009-01-05
  • 打赏
  • 举报
回复

是的,的确是对input的值进行计算,我没仔细考虑。

上面出现3个版本的Func,整理如下,不知道是否如此 :(



static __inline__ unsigned int Func(unsigned int input); // v1 错误
static __inline__ unsigned int Func(volatile unsigned int input); // v2 正确
static unsigned int Func(unsigned int input); // v3 正确



没有学过MIPS汇编,不过比较了一下。v1版264开始的代码,先从栈中装载第1个字节到寄存器,然后将字(这个应该是input)存放到栈上,之后再从栈上装载第0,2,3字节到寄存器。
这似乎与其它两个正确版本不同。也不知道是不是这个地方影响了结果。

v1版ValueGet中,汇编代码,对上面的内容似乎是正确的。

是否考虑单独测试一下这两个函数ValueAdd和ValueGet。有可能的话用调试器追一下。
dreamuser 2009-01-04
  • 打赏
  • 举报
回复
非常感谢楼上各位大虾的意见。
补充说明:

1) unsigned char *pval = (unsigned char *)&input;
这里是没有问题的,这只是指针类型的强制转化,指向数据空间的首地址,因此可以通过pval(指向4维字符数组)数组下标来访问,不存在pVal[1],pVal[2],pVal[3]访问越界。

2)
temp1 = (unsigned int)(pval[0] ^ pval[1]);
temp2 = (unsigned int)(pval[2] ^ pval[3]);
我也曾试过把上面的代码改为:

temp1 = (pval[0] ^ pval[1]);
temp2 = (pval[2] ^ pval[3]);
现象和上面一样。所以这里不会有问题。理论上分析也不会有问题,只是数据类型强制转化。


3)在函数入口处打印其值时,是对的。这和在函数入口处加printf("");是一样的结果。


4)volatile好像更多用在接近硬件层,在应用上用得比较少(这个函数是用在应用层上的)。当然不排除与多线程有某种关系,只是我现在还没有找到它与多线程有关。因为代码量很大,可能我还理解的不透撤。

5) __inline__是GCC的编译选项,但查了一下有关GCC的文档,也没发现什么特别的地方。


请高手多多指教!!
Thank you!!
dreamuser 2009-01-04
  • 打赏
  • 举报
回复
C) 函数定义:static unsigned int Func(unsigned int input)
file format elf32-littlemips

Disassembly of section .text:

0000000000000000 <ValueGetNew>:
0: 3c020000 lui $v0,0x0
4: 8c420000 lw $v0,0($v0)
8: 27bdffd0 addiu $sp,$sp,-48
c: ffbf0028 sd $ra,40($sp)
10: 24420001 addiu $v0,$v0,1
14: 2c430240 sltiu $v1,$v0,576
18: ffb00020 sd $s0,32($sp)
1c: 3c010000 lui $at,0x0
20: ac220000 sw $v0,0($at)
24: 14600003 bnez $v1,34 <ValueGetNew+0x34>
28: 24020016 li $v0,22
2c: 3c010000 lui $at,0x0
30: ac220000 sw $v0,0($at)
34: 3c050000 lui $a1,0x0
38: 8ca50000 lw $a1,0($a1)
3c: 3c040000 lui $a0,0x0
40: 64840004 daddiu $a0,$a0,4
44: 000510c0 sll $v0,$a1,0x3
48: 00441021 addu $v0,$v0,$a0
4c: 8c430000 lw $v1,0($v0)
50: 14600005 bnez $v1,68 <ValueGetNew+0x68>
54: 248300b0 addiu $v1,$a0,176
58: 00a0802d move $s0,$a1
5c: ac500000 sw $s0,0($v0)
60: 08000033 j cc <ValueGetNew+0xcc>
64: 0200102d move $v0,$s0
68: 24100016 li $s0,22
6c: 08000020 j 80 <ValueGetNew+0x80>
70: 0000202d move $a0,$zero
74: 00000000 nop
78: 24630008 addiu $v1,$v1,8
7c: 26100001 addiu $s0,$s0,1
80: 2e020240 sltiu $v0,$s0,576
84: 1040000e beqz $v0,c0 <ValueGetNew+0xc0>
88: 00000000 nop
8c: 8c620000 lw $v0,0($v1)
90: 1440fff9 bnez $v0,78 <ValueGetNew+0x78>
94: 00000000 nop
98: 3c020000 lui $v0,0x0
9c: 8c420000 lw $v0,0($v0)
a0: 30420001 andi $v0,$v0,0x1
a4: 10400005 beqz $v0,bc <ValueGetNew+0xbc>
a8: ac700000 sw $s0,0($v1)
ac: 3c040000 lui $a0,0x0
b0: 64840000 daddiu $a0,$a0,0
b4: 0c000000 jal 0 <ValueGetNew>
b8: 0200282d move $a1,$s0
bc: 24040001 li $a0,1
c0: 14800002 bnez $a0,cc <ValueGetNew+0xcc>
c4: 0200102d move $v0,$s0
c8: 0000102d move $v0,$zero
cc: dfbf0028 ld $ra,40($sp)
d0: dfb00020 ld $s0,32($sp)
d4: 03e00008 jr $ra
d8: 27bd0030 addiu $sp,$sp,48
dc: 00000000 nop



0000000000000238 <Func>:
238: afa40000 sw $a0,0($sp)
23c: 93a30000 lbu $v1,0($sp)
240: 93a40001 lbu $a0,1($sp)
244: 93a50003 lbu $a1,3($sp)
248: 93a20002 lbu $v0,2($sp)
24c: 00641826 xor $v1,$v1,$a0
250: 00031900 sll $v1,$v1,0x4
254: 00451026 xor $v0,$v0,$a1
258: 03e00008 jr $ra
25c: 00621026 xor $v0,$v1,$v0

0000000000000260 <ValueAdd>:
260: 27bdffc8 addiu $sp,$sp,-56
264: ffbf0030 sd $ra,48($sp)
268: ffb10028 sd $s1,40($sp)
26c: ffb00020 sd $s0,32($sp)
270: 0080882d move $s1,$a0
274: 3c040000 lui $a0,0x0
278: 64840038 daddiu $a0,$a0,56
27c: 0c000000 jal 0 <ValueGetNew>
280: 8e250020 lw $a1,32($s1)
284: 0c00008e jal 238 <Func>
288: 8e240020 lw $a0,32($s1)
28c: 0040802d move $s0,$v0
290: 0200282d move $a1,$s0
294: 3c040000 lui $a0,0x0
298: 64840050 daddiu $a0,$a0,80
29c: 0c000000 jal 0 <ValueGetNew>
2a0: 00108080 sll $s0,$s0,0x2
2a4: 3c050000 lui $a1,0x0
2a8: 64a50000 daddiu $a1,$a1,0
2ac: 00b0282d daddu $a1,$a1,$s0
2b0: 8ca20000 lw $v0,0($a1)
2b4: 3c010000 lui $at,0x0
2b8: 64210000 daddiu $at,$at,0
2bc: 0030802d daddu $s0,$at,$s0
2c0: 8e030000 lw $v1,0($s0)
2c4: 24420001 addiu $v0,$v0,1
2c8: aca20000 sw $v0,0($a1)
2cc: 3c040000 lui $a0,0x0
2d0: 64840058 daddiu $a0,$a0,88
2d4: ae230064 sw $v1,100($s1)
2d8: 0c000000 jal 0 <ValueGetNew>
2dc: 0060282d move $a1,$v1
2e0: dfbf0030 ld $ra,48($sp)
2e4: ae110000 sw $s1,0($s0)
2e8: dfb10028 ld $s1,40($sp)
2ec: dfb00020 ld $s0,32($sp)
2f0: 03e00008 jr $ra
2f4: 27bd0038 addiu $sp,$sp,56


0000000000000380 <ValueGet>:
380: 27bdffc8 addiu $sp,$sp,-56
384: ffb10028 sd $s1,40($sp)
388: 0080882d move $s1,$a0
38c: 3c040000 lui $a0,0x0
390: 64840078 daddiu $a0,$a0,120
394: ffb00020 sd $s0,32($sp)
398: ffbf0030 sd $ra,48($sp)
39c: 0c000000 jal 0 <ValueGetNew>
3a0: 0220282d move $a1,$s1
3a4: 0c00008e jal 238 <Func>
3a8: 0220202d move $a0,$s1
3ac: 0040802d move $s0,$v0
3b0: 0200282d move $a1,$s0
3b4: 3c040000 lui $a0,0x0
3b8: 64840098 daddiu $a0,$a0,152
3bc: 0c000000 jal 0 <ValueGetNew>
3c0: 00108080 sll $s0,$s0,0x2
3c4: 3c010000 lui $at,0x0
3c8: 0030082d daddu $at,$at,$s0
3cc: 8c300000 lw $s0,0($at)
3d0: 080000f7 j 3dc <ValueGet+0x5c>
3d4: 00000000 nop
3d8: 8e100064 lw $s0,100($s0)
3dc: 1200000c beqz $s0,410 <ValueGet+0x90>
3e0: 0200102d move $v0,$s0
3e4: 3c040000 lui $a0,0x0
3e8: 648400b0 daddiu $a0,$a0,176
3ec: 0c000000 jal 0 <ValueGetNew>
3f0: 8e050020 lw $a1,32($s0)
3f4: 3c040000 lui $a0,0x0
3f8: 648400c8 daddiu $a0,$a0,200
3fc: 0c000000 jal 0 <ValueGetNew>
400: 0220282d move $a1,$s1
404: 8e030020 lw $v1,32($s0)
408: 1471fff3 bne $v1,$s1,3d8 <ValueGet+0x58>
40c: 0200102d move $v0,$s0
410: dfbf0030 ld $ra,48($sp)
414: dfb10028 ld $s1,40($sp)
418: dfb00020 ld $s0,32($sp)
41c: 03e00008 jr $ra
420: 27bd0038 addiu $sp,$sp,56
424: 00000000 nop
dreamuser 2009-01-04
  • 打赏
  • 举报
回复
b) 函数定义:static __inline__ unsigned int Func(volatile unsigned int input)
file format elf32-littlemips

Disassembly of section .text:

0000000000000000 <ValueGetNew>:
0: 3c020000 lui $v0,0x0
4: 8c420000 lw $v0,0($v0)
8: 27bdffd0 addiu $sp,$sp,-48
c: ffbf0028 sd $ra,40($sp)
10: 24420001 addiu $v0,$v0,1
14: 2c430240 sltiu $v1,$v0,576
18: ffb00020 sd $s0,32($sp)
1c: 3c010000 lui $at,0x0
20: ac220000 sw $v0,0($at)
24: 14600003 bnez $v1,34 <ValueGetNew+0x34>
28: 24020016 li $v0,22
2c: 3c010000 lui $at,0x0
30: ac220000 sw $v0,0($at)
34: 3c050000 lui $a1,0x0
38: 8ca50000 lw $a1,0($a1)
3c: 3c040000 lui $a0,0x0
40: 64840004 daddiu $a0,$a0,4
44: 000510c0 sll $v0,$a1,0x3
48: 00441021 addu $v0,$v0,$a0
4c: 8c430000 lw $v1,0($v0)
50: 14600005 bnez $v1,68 <ValueGetNew+0x68>
54: 248300b0 addiu $v1,$a0,176
58: 00a0802d move $s0,$a1
5c: ac500000 sw $s0,0($v0)
60: 08000033 j cc <ValueGetNew+0xcc>
64: 0200102d move $v0,$s0
68: 24100016 li $s0,22
6c: 08000020 j 80 <ValueGetNew+0x80>
70: 0000202d move $a0,$zero
74: 00000000 nop
78: 24630008 addiu $v1,$v1,8
7c: 26100001 addiu $s0,$s0,1
80: 2e020240 sltiu $v0,$s0,576
84: 1040000e beqz $v0,c0 <ValueGetNew+0xc0>
88: 00000000 nop
8c: 8c620000 lw $v0,0($v1)
90: 1440fff9 bnez $v0,78 <ValueGetNew+0x78>
94: 00000000 nop
98: 3c020000 lui $v0,0x0
9c: 8c420000 lw $v0,0($v0)
a0: 30420001 andi $v0,$v0,0x1
a4: 10400005 beqz $v0,bc <ValueGetNew+0xbc>
a8: ac700000 sw $s0,0($v1)
ac: 3c040000 lui $a0,0x0
b0: 64840000 daddiu $a0,$a0,0
b4: 0c000000 jal 0 <ValueGetNew>
b8: 0200282d move $a1,$s0
bc: 24040001 li $a0,1
c0: 14800002 bnez $a0,cc <ValueGetNew+0xcc>
c4: 0200102d move $v0,$s0
c8: 0000102d move $v0,$zero
cc: dfbf0028 ld $ra,40($sp)
d0: dfb00020 ld $s0,32($sp)
d4: 03e00008 jr $ra
d8: 27bd0030 addiu $sp,$sp,48
dc: 00000000 nop


0000000000000238 <ValueAdd>:
238: 27bdffa8 addiu $sp,$sp,-88
23c: ffbf0050 sd $ra,80($sp)
240: ffb10048 sd $s1,72($sp)
244: ffb00040 sd $s0,64($sp)
248: 0080882d move $s1,$a0
24c: 3c040000 lui $a0,0x0
250: 64840038 daddiu $a0,$a0,56
254: 0c000000 jal 0 <ValueGetNew>
258: 8e250020 lw $a1,32($s1)
25c: 8e230020 lw $v1,32($s1)
260: 3c040000 lui $a0,0x0
264: 64840050 daddiu $a0,$a0,80
268: afa30020 sw $v1,32($sp)
26c: 93a30021 lbu $v1,33($sp)
270: 93b00020 lbu $s0,32($sp)
274: 93a50023 lbu $a1,35($sp)
278: 93a20022 lbu $v0,34($sp)
27c: 02038026 xor $s0,$s0,$v1
280: 00108100 sll $s0,$s0,0x4
284: 00451026 xor $v0,$v0,$a1
288: 02028026 xor $s0,$s0,$v0
28c: 0200282d move $a1,$s0
290: 0c000000 jal 0 <ValueGetNew>
294: 00108080 sll $s0,$s0,0x2
298: 3c050000 lui $a1,0x0
29c: 64a50000 daddiu $a1,$a1,0
2a0: 00b0282d daddu $a1,$a1,$s0
2a4: 8ca20000 lw $v0,0($a1)
2a8: 3c010000 lui $at,0x0
2ac: 64210000 daddiu $at,$at,0
2b0: 0030802d daddu $s0,$at,$s0
2b4: 8e030000 lw $v1,0($s0)
2b8: 24420001 addiu $v0,$v0,1
2bc: aca20000 sw $v0,0($a1)
2c0: 3c040000 lui $a0,0x0
2c4: 64840058 daddiu $a0,$a0,88
2c8: ae230064 sw $v1,100($s1)
2cc: 0c000000 jal 0 <ValueGetNew>
2d0: 0060282d move $a1,$v1
2d4: dfbf0050 ld $ra,80($sp)
2d8: ae110000 sw $s1,0($s0)
2dc: dfb10048 ld $s1,72($sp)
2e0: dfb00040 ld $s0,64($sp)
2e4: 03e00008 jr $ra
2e8: 27bd0058 addiu $sp,$sp,88
2ec: 00000000 nop


0000000000000388 <ValueGet>:
388: 27bdffa8 addiu $sp,$sp,-88
38c: ffb10048 sd $s1,72($sp)
390: 0080882d move $s1,$a0
394: 3c040000 lui $a0,0x0
398: 64840078 daddiu $a0,$a0,120
39c: ffb00040 sd $s0,64($sp)
3a0: ffbf0050 sd $ra,80($sp)
3a4: 0c000000 jal 0 <ValueGetNew>
3a8: 0220282d move $a1,$s1
3ac: afb10020 sw $s1,32($sp)
3b0: 93b00020 lbu $s0,32($sp)
3b4: 93a30021 lbu $v1,33($sp)
3b8: 93a40023 lbu $a0,35($sp)
3bc: 93a20022 lbu $v0,34($sp)
3c0: 02038026 xor $s0,$s0,$v1
3c4: 00108100 sll $s0,$s0,0x4
3c8: 00441026 xor $v0,$v0,$a0
3cc: 02028026 xor $s0,$s0,$v0
3d0: 0200282d move $a1,$s0
3d4: 3c040000 lui $a0,0x0
3d8: 64840098 daddiu $a0,$a0,152
3dc: 0c000000 jal 0 <ValueGetNew>
3e0: 00108080 sll $s0,$s0,0x2
3e4: 3c010000 lui $at,0x0
3e8: 0030082d daddu $at,$at,$s0
3ec: 8c300000 lw $s0,0($at)
3f0: 080000ff j 3fc <ValueGet+0x74>
3f4: 00000000 nop
3f8: 8e100064 lw $s0,100($s0)
3fc: 1200000c beqz $s0,430 <ValueGet+0xa8>
400: 0200102d move $v0,$s0
404: 3c040000 lui $a0,0x0
408: 648400b0 daddiu $a0,$a0,176
40c: 0c000000 jal 0 <ValueGetNew>
410: 8e050020 lw $a1,32($s0)
414: 3c040000 lui $a0,0x0
418: 648400c8 daddiu $a0,$a0,200
41c: 0c000000 jal 0 <ValueGetNew>
420: 0220282d move $a1,$s1
424: 8e030020 lw $v1,32($s0)
428: 1471fff3 bne $v1,$s1,3f8 <ValueGet+0x70>
42c: 0200102d move $v0,$s0
430: dfbf0050 ld $ra,80($sp)
434: dfb10048 ld $s1,72($sp)
438: dfb00040 ld $s0,64($sp)
43c: 03e00008 jr $ra
440: 27bd0058 addiu $sp,$sp,88
444: 00000000 nop

dreamuser 2009-01-04
  • 打赏
  • 举报
回复
说明:
1) ValueAdd是用于设置操作,它调用了Func
2) ValueGet是用于查询操作,它也调用Func
3) ValueGetNew被ValueAdd或ValueGet调用
4) 下面的汇编代码是用Tornado2.2(for MIPS cpu)带的工具:objdumpmips.exe根据.a文件产生的汇编。因为CPU类型是MIPS,所以汇编指令也是针对MIPS的专门指令
5) 去掉无关的代码

汇编代码如下:
a) 函数定义:static __inline__ unsigned int Func(unsigned int input)
file format elf32-littlemips

Disassembly of section .text:

0000000000000000 <ValueGetNew>:
0: 3c020000 lui $v0,0x0
4: 8c420000 lw $v0,0($v0)
8: 27bdffd0 addiu $sp,$sp,-48
c: ffbf0028 sd $ra,40($sp)
10: 24420001 addiu $v0,$v0,1
14: 2c430240 sltiu $v1,$v0,576
18: ffb00020 sd $s0,32($sp)
1c: 3c010000 lui $at,0x0
20: ac220000 sw $v0,0($at)
24: 14600003 bnez $v1,34 <ValueGetNew+0x34>
28: 24020016 li $v0,22
2c: 3c010000 lui $at,0x0
30: ac220000 sw $v0,0($at)
34: 3c050000 lui $a1,0x0
38: 8ca50000 lw $a1,0($a1)
3c: 3c040000 lui $a0,0x0
40: 64840004 daddiu $a0,$a0,4
44: 000510c0 sll $v0,$a1,0x3
48: 00441021 addu $v0,$v0,$a0
4c: 8c430000 lw $v1,0($v0)
50: 14600005 bnez $v1,68 <ValueGetNew+0x68>
54: 248300b0 addiu $v1,$a0,176
58: 00a0802d move $s0,$a1
5c: ac500000 sw $s0,0($v0)
60: 08000033 j cc <ValueGetNew+0xcc>
64: 0200102d move $v0,$s0
68: 24100016 li $s0,22
6c: 08000020 j 80 <ValueGetNew+0x80>
70: 0000202d move $a0,$zero
74: 00000000 nop
78: 24630008 addiu $v1,$v1,8
7c: 26100001 addiu $s0,$s0,1
80: 2e020240 sltiu $v0,$s0,576
84: 1040000e beqz $v0,c0 <ValueGetNew+0xc0>
88: 00000000 nop
8c: 8c620000 lw $v0,0($v1)
90: 1440fff9 bnez $v0,78 <ValueGetNew+0x78>
94: 00000000 nop
98: 3c020000 lui $v0,0x0
9c: 8c420000 lw $v0,0($v0)
a0: 30420001 andi $v0,$v0,0x1
a4: 10400005 beqz $v0,bc <ValueGetNew+0xbc>
a8: ac700000 sw $s0,0($v1)
ac: 3c040000 lui $a0,0x0
b0: 64840000 daddiu $a0,$a0,0
b4: 0c000000 jal 0 <ValueGetNew>
b8: 0200282d move $a1,$s0
bc: 24040001 li $a0,1
c0: 14800002 bnez $a0,cc <ValueGetNew+0xcc>
c4: 0200102d move $v0,$s0
c8: 0000102d move $v0,$zero
cc: dfbf0028 ld $ra,40($sp)
d0: dfb00020 ld $s0,32($sp)
d4: 03e00008 jr $ra
d8: 27bd0030 addiu $sp,$sp,48
dc: 00000000 nop


0000000000000238 <ValueAdd>:
238: 27bdffa0 addiu $sp,$sp,-96
23c: ffbf0058 sd $ra,88($sp)
240: ffb10050 sd $s1,80($sp)
244: ffb00048 sd $s0,72($sp)
248: 0080882d move $s1,$a0
24c: 3c040000 lui $a0,0x0
250: 64840038 daddiu $a0,$a0,56
254: 0c000000 jal 0 <ValueGetNew>
258: 8e250020 lw $a1,32($s1)
25c: 8e240020 lw $a0,32($s1)
260: 27a30040 addiu $v1,$sp,64
264: 90650001 lbu $a1,1($v1)
268: afa40040 sw $a0,64($sp)
26c: 93b00040 lbu $s0,64($sp)
270: 90640003 lbu $a0,3($v1)
274: 90620002 lbu $v0,2($v1)
278: 02058026 xor $s0,$s0,$a1
27c: 00108100 sll $s0,$s0,0x4
280: 00441026 xor $v0,$v0,$a0
284: 02028026 xor $s0,$s0,$v0
288: 0200282d move $a1,$s0
28c: 3c040000 lui $a0,0x0
290: 64840050 daddiu $a0,$a0,80
294: 0c000000 jal 0 <ValueGetNew>
298: 00108080 sll $s0,$s0,0x2
29c: 3c050000 lui $a1,0x0
2a0: 64a50000 daddiu $a1,$a1,0
2a4: 00b0282d daddu $a1,$a1,$s0
2a8: 8ca20000 lw $v0,0($a1)
2ac: 3c010000 lui $at,0x0
2b0: 64210000 daddiu $at,$at,0
2b4: 0030802d daddu $s0,$at,$s0
2b8: 8e030000 lw $v1,0($s0)
2bc: 24420001 addiu $v0,$v0,1
2c0: aca20000 sw $v0,0($a1)
2c4: 3c040000 lui $a0,0x0
2c8: 64840058 daddiu $a0,$a0,88
2cc: ae230064 sw $v1,100($s1)
2d0: 0c000000 jal 0 <ValueGetNew>
2d4: 0060282d move $a1,$v1
2d8: dfbf0058 ld $ra,88($sp)
2dc: ae110000 sw $s1,0($s0)
2e0: dfb10050 ld $s1,80($sp)
2e4: dfb00048 ld $s0,72($sp)
2e8: 03e00008 jr $ra
2ec: 27bd0060 addiu $sp,$sp,96



0000000000000388 <ValueGet>:
388: 27bdffa0 addiu $sp,$sp,-96
38c: ffb10050 sd $s1,80($sp)
390: 0080882d move $s1,$a0
394: 3c040000 lui $a0,0x0
398: 64840078 daddiu $a0,$a0,120
39c: ffb00048 sd $s0,72($sp)
3a0: ffbf0058 sd $ra,88($sp)
3a4: 0c000000 jal 0 <ValueGetNew>
3a8: 0220282d move $a1,$s1
3ac: afb10040 sw $s1,64($sp)
3b0: 27a20040 addiu $v0,$sp,64
3b4: 90440001 lbu $a0,1($v0)
3b8: 93b00040 lbu $s0,64($sp)
3bc: 90450003 lbu $a1,3($v0)
3c0: 90430002 lbu $v1,2($v0)
3c4: 02048026 xor $s0,$s0,$a0
3c8: 00108100 sll $s0,$s0,0x4
3cc: 00651826 xor $v1,$v1,$a1
3d0: 02038026 xor $s0,$s0,$v1
3d4: 0200282d move $a1,$s0
3d8: 3c040000 lui $a0,0x0
3dc: 64840098 daddiu $a0,$a0,152
3e0: 0c000000 jal 0 <ValueGetNew>
3e4: 00108080 sll $s0,$s0,0x2
3e8: 3c010000 lui $at,0x0
3ec: 0030082d daddu $at,$at,$s0
3f0: 8c300000 lw $s0,0($at)
3f4: 08000101 j 404 <ValueGet+0x7c>
...
400: 8e100064 lw $s0,100($s0)
404: 1200000c beqz $s0,438 <ValueGet+0xb0>
408: 0200102d move $v0,$s0
40c: 3c040000 lui $a0,0x0
410: 648400b0 daddiu $a0,$a0,176
414: 0c000000 jal 0 <ValueGetNew>
418: 8e050020 lw $a1,32($s0)
41c: 3c040000 lui $a0,0x0
420: 648400c8 daddiu $a0,$a0,200
424: 0c000000 jal 0 <ValueGetNew>
428: 0220282d move $a1,$s1
42c: 8e030020 lw $v1,32($s0)
430: 1471fff3 bne $v1,$s1,400 <ValueGet+0x78>
434: 0200102d move $v0,$s0
438: dfbf0058 ld $ra,88($sp)
43c: dfb10050 ld $s1,80($sp)
440: dfb00048 ld $s0,72($sp)
444: 03e00008 jr $ra
448: 27bd0060 addiu $sp,$sp,96
44c: 00000000 nop

rogersun 2009-01-04
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 yutaooo 的回复:]

哦。我错了。已经有取地址操作了 (&input),input必定在内存上,不会分配寄存器给它的。

我有个疑问,你取栈上局部变量的地址,并对它计算,是你的本意吗?栈可是在不停的增长收缩的。

还是强烈建议输出汇编了看看。
[/Quote]

不是对局部变量的地址进行计算,是对input的值进行计算。pVal是指向了input的第一个字节。

yutaooo 2009-01-04
  • 打赏
  • 举报
回复

哦。我错了。已经有取地址操作了 (&input),input必定在内存上,不会分配寄存器给它的。

我有个疑问,你取栈上局部变量的地址,并对它计算,是你的本意吗?栈可是在不停的增长收缩的。

还是强烈建议输出汇编了看看。
hiji 2009-01-04
  • 打赏
  • 举报
回复
1) unsigned char *pval = (unsigned char *)&input;
这里是没有问题的,这只是指针类型的强制转化,指向数据空间的首地址,因此可以通过pval(指向4维字符数组)数组下标来访问,不存在pVal[1],pVal[2],pVal[3]访问越界。

这里取的是临时变量的地址吧
yutaooo 2009-01-04
  • 打赏
  • 举报
回复

我怀疑是编译器优化导致的后果。当然,如果优化造成结果不一致是很严重的。找volatile和非volatile版本,各自输出汇编吧。贴来看看。

编译命令行也贴一下吧。

volatile常在多线程程序中出现,但这不是本意呀。本意是保持变量在内存上。不加很有可能选用一个寄存器了的。volatile也被用作阻碍优化的语意用的。
zxymythsky 2009-01-04
  • 打赏
  • 举报
回复
建议楼主自己先搭建一个测试环境,相对独立地测测这个函数。
zenny_chen 2009-01-04
  • 打赏
  • 举报
回复
建议楼主自己先搭建一个测试环境,相对独立地测测这个函数。
yqsofter 2009-01-03
  • 打赏
  • 举报
回复
pVal的大小应该为1,pVal[1],pVal[2],pVal[3]访问越界了,它们的值是不定的。所以每次调用的结果应该是不同的。
至于有时是正确是因为在特定的环境中不同的调用之间pVal[1],pVal[2],pVal[3]的数值是相同的,但是换了环境就同样会出现问题的。
ltc_mouse 2009-01-03
  • 打赏
  • 举报
回复
input是什么东西呢? 感觉像是缺少了必要的延时~
加载更多回复(6)
标题SpringBoot与Android融合的智慧旅游平台设计研究AI更换标题第1章引言阐述智慧旅游的发展背景、SpringBoot与Android技术结合的意义、国内外研究现状及论文创新点。1.1研究背景与意义分析智慧旅游行业现状及平台建设的必要性。1.2国内外研究现状综述国内外智慧旅游平台的研究进展。1.3研究方法及创新点介绍本文采用的研究方法和技术创新点。第2章相关理论总结SpringBoot、Android开发及智慧旅游相关理论。2.1SpringBoot框架原理介绍SpringBoot框架的核心特性与优势。2.2Android开发基础阐述Android系统的架构及开发环境搭建。2.3智慧旅游概念及应用解释智慧旅游的定义及其在旅游业中的应用场景。第3章平台设计详细介绍基于SpringBoot与Android的智慧旅游平台设计方案。3.1平台架构设计平台的整体架构,包括前端、后端及数据库设计。3.2功能模块设计分析平台的主要功能模块,如景点推荐、导航、用户管理等。3.3数据库设计阐述数据库的设计思路,包括表结构、关系等。第4章平台实现介绍平台的具体实现过程,包括前端界面开发、后端服务搭建及数据库实现。4.1Android前端界面开发介绍Android前端界面的设计与实现方法。4.2SpringBoot后端服务搭建阐述后端服务的搭建过程,包括API设计、接口实现等。4.3数据库实现与优化介绍数据库的实现细节及优化策略。第5章实验与分析对平台进行实验验证,分析实验结果,评估平台性能。5.1实验环境与数据介绍实验环境、测试数据及评估指标。5.2实验方法与步骤实验的具体方法和步骤,包括功能测试、性能测试等。5.3实验结果与分析根据实验结果,分析平台的性能及存在的问题。第6章结论与展望总结平台设计与实现的主要成果,提出未来改进方向。6.1研究结论概括平台设计与实现的主要成果和创
标题SpringBoot与Android结合的健康饮食推荐系统研究AI更换标题第1章引言阐述健康饮食推荐系统的研究背景、意义、国内外研究现状、论文方法及创新点。1.1研究背景与意义分析健康饮食需求增长及传统推荐系统的不足,说明系统开发必要性。1.2国内外研究现状综述国内外健康饮食推荐系统的研究进展与存在的问题。1.3研究方法及创新点介绍SpringBoot与Android结合的开发方法及系统创新点。第2章相关理论总结健康饮食推荐系统涉及的理论基础,立研究基石。2.1健康饮食理论阐述健康饮食的基本原则、营养搭配等理论知识。2.2推荐系统理论介绍推荐系统的基本原理、算法分类及适用场景。2.3SpringBoot与Android开发理论概述SpringBoot框架和Android开发平台的特点及应用。第3章系统设计详细描述健康饮食推荐系统的整体设计方案。3.1系统架构设计介绍系统的总体架构,包括前端、后端及数据库设计。3.2功能模块设计阐述用户管理、饮食记录、推荐算法等核心模块的设计思路。3.3数据库设计说明数据库表结构、字段设计及数据关系。第4章研究方法详细描述系统开发过程中的模型设计、数据收集和分析方法。4.1模型设计介绍推荐算法模型的选择、构建及优化过程。4.2数据收集方法说明用户饮食数据、健康数据等数据的收集途径和方式。4.3数据分析方法阐述对收集到的数据进行处理、分析的方法和技术。第5章研究结果呈现系统开发完成后的实验分析结果。5.1系统实现效果展示系统界面、功能实现情况及用户交互体验。5.2推荐准性分析通过对比实验,分析推荐算法的准性和有效性。5.3用户满意度调查通过问卷调查等方式,收集用户对系统的满意度反馈。第6章结论与展望总结研究成果,并提出未来研究方向。6.1研究结论概括系统开发的主要成果,包括功能实现、推荐效果等。6.2展望指出系统存在的不足,提出改进方

70,026

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧