原文地址:https://blog.csdn.net/zhzht19861011/article/details/6344767
最近编写一个程序,其中有下面一句,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. 两个表达式想运算或比较时,都加括号,让编译器去郁闷吧.
|