最近编写一个程序,其中有下面一句,g_ucTimeValue[0]=0x23,但表示的却是十进制的23,我想使用下句代码将这个十进制的23变成十六进制的0x17,但结果d的值却是0x07,为了查找根源,对这句C语言进行反汇编.
d=(g_ucTimeValue[0]>>4)*10+g_ucTimeValue[0]&0x0F; //十进制转化为16进制v
反汇编代码如下(红色为注释):
198: d=(g_ucTimeValue[0]>>4)*10+g_ucTimeValue[0]&0x0F; //十进制转化为16进制
C:0x0750 788C MOV R0,#g_ucTimeValue(0x8C) 将g_ucTimeValue[0]的地址给R0
C:0x0752 E6 MOV A,@R0 取到g_ucTimeValue[0]中的值,A=0x23
C:0x0753 FE MOV R6,A R6=0x23
C:0x0754 C4 SWAP A 高四位和第四位翻转,A=0x32
C:0x0755 540F ANL A,#0x0F A=0x02
C:0x0757 75F00A MOV B(0xF0),#0x0A B=0x0A
C:0x075A A4 MUL AB A=A*B=0x14
C:0x075B 2E ADD A,R6 A=A+R0=0x37
C:0x075C 540F ANL A,#0x0F A=0x07
C:0x075E FE MOV R6,A R6=0x07
C:0x075F 7895 MOV R0,#TMR3H(0x95) 附地址
C:0x0761 F6 MOV @R0,A 传送值
C:0x0762 FB MOV R3,A 保存结果=0x07
将上述语句改成 d=(g_ucTimeValue[0]>>4)*10+(g_ucTimeValue[0]&0x0F); 问题解决.
像这个语句: #define READSDA IO0PIN&(1<<11) //读IO口p0.11的端口状态
判断p0.11端口是否为高电平,使用下述语句就是错误的:
if(READSDA==(1<<11))
{
//是高电平,处理高电平的问题
}
编译器在编译后将宏带入,原if语句变为:
if(IO0PIN&(1<<11) ==(1<<11))
{
//是高电平,处理高电平的问题
}
这样的话,运算符'=='的优先级是大于'&'的,从而IO0PIN&(1<<11) ==(1<<11))语句等效为IO0PIN&0x00000001,与原意相差甚远.
总结:1. 尽量掌握优先级
2. 两个表达式想运算或比较时,都加括号,让编译器去郁闷吧.