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

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!!
...全文
1718 26 打赏 收藏 转发到动态 举报
写回复
用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)
资源下载链接为: https://pan.quark.cn/s/f1ead55c4354 以下标题“H5页面模板源码,很不错的例子”暗示了我们讨论的主题是关于HTML5页面模板的源代码。HTML5是现代网页开发的核心技术,它提供了丰富的功能和元素,让开发者能够构建出更具交互性、动态性和响应式的网页。“很不错的例子”表明这些源码不仅具有实用性,还具备一定的教学意义,既可以作为项目开发的直接素材,也能供学习参考。 在描述“H5页面模板源码,非常酷炫的HTML5模板,可以直接使用,也可以参考学习”中,“非常酷炫”意味着这些模板可能融合了诸多高级特性,例如动画效果、媒体元素的运用以及响应式设计等,这些都是HTML5技术的优势所在。可以直接使用表明用户无需从零开始编写代码,能迅速搭建出吸引人的网页。同时,这些模板也适合学习,用户通过查看源代码可以了解特定设计和功能的实现方式,从而提升自身的HTML5开发能力。 标签“H5 手机网页 H5源代码 手机html”进一步明了主题。“H5”是HTML5的简称,“手机网页”和“手机html”则强调这些模板是针对移动设备优化的。在如今移动优先的时代,适应各种屏幕尺寸和触摸操作的网页设计极为重要。这表明这些源码很可能是响应式的,能够根据设备自动调整布局,以适配手机、平板电脑等多种设备。 从“压缩包文件的文件名称列表”来看,虽然无法直接从文件名得知具体源码内容,但可以推测这些文件可能包含多种HTML5模板示例。“不错的样子.txt”可能是一个介绍或说明文件,对模板进行简要描述或提供使用指南。而“1-30”这样的命名方式可能意味着有30个不同的模板实例,每个模板对应一个独立文件,涵盖多种设计风格和功能,为学习和实践提供了全面的平台。 总的来说,这个资源集合为HTML5开发者或初学者提供了一套实用且酷炫的移动网页模板源代码。这些模板既可以直接应用于项目

70,016

社区成员

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

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