c语言两个无符号字符赋值,用VC来解释C语言中有符号和无符号数据相加和赋值的问题...

近来在写程序的时候遇到一个问题,由于平时比较忙,也都没仔细想过不同数据类型相加的问题,特别是有符号和无符号相加的问题,结果在输出结果的时候发现总是不对,后来仔细问题才发现问题所在,这里写出来以供大家学习参考.

问题如下:

已知

char *pData = buf[3];

pData[0] = 0x03;

pDatap1] = 0xe8;

unsigned short src_port = (pData[0]

<< 8) + (USHORT)pData[1];

问src_port的结果是多少?

我们可以用VC产生的汇编看看:

1.原等式

unsigned short src_port = (pData[0]

<< 8) + (USHORT)pData[1];

00401AEE mov eax,dword ptr [ebp-14h]

00401AF1 movsx ecx,byte ptr [eax]/** ①注意到这里没有 **/

00401AF4 shl ecx,8

00401AF7 mov edx,dword ptr [ebp-14h]

00401AFA movsx eax,byte ptr [edx+1]

00401AFE add ecx,eax

00401B00 mov word ptr [src_port],cx

2.使用0xe8代替pData[1]

unsigned short src_port = (pData[0]

<< 8) + 0xe8;

00401AEE mov eax,dword ptr [ebp-14h]

00401AF1 movsx ecx,byte ptr [eax]/** ②注意到这里没有 **/

00401AF4 shl ecx,8

00401AF7 add ecx,0E8h

00401AFD mov word ptr [src_port],cx

猜猜看上面的两个结果是什么?

1.0x02e8

2.0x03e8

让我们来改个写法来看看结果:

3.把pdata修改为unsigned:

unsigned char *pData =

buf[3];

看看产生的汇编:

464: unsigned

short src_port = (pData[0] << 8) + pData[1];;

00410AFF mov eax,dword ptr [ebp-14h]

00410B02 xor ecx,ecx

00410B04 mov cl,byte ptr [eax]/** ③注意到这里没有 **/

00410B06 shl ecx,8

00410B09 mov edx,dword ptr [ebp-14h]

00410B0C xor eax,eax

00410B0E mov al,byte ptr [edx+1]

00410B11 add ecx,eax

00410B13 mov word ptr [src_port],cx

我想细心的人已经注意到了我给的标注①②③,仔细对比它们的意思,我们可以发现,对于有符号和无符号的取值产生的汇编是不一样,而就是由于取值的不同,就会导致输出的不同,而其中的关键其实就是有符号-->无符号的转换.

这里的转换是字节byte ptr

[eax](pdata[0]的值)-->ecx(32位)的转换,而这种转换存在隐式规则,当符号位为1时,转换为多字节后,高位字节补为全1,即0xe8

-->

0xffffff88.那么我们就可以知道1、2问题的计算结果是如何得来的了:

1。 0x0300 + 0xffe8 = 0x02e8

2. 0x0300 + 0x00e8 = 0x03e8

在这里还涉及到读汇编代码时的一些积存器的意思,下面简单附一些解释:

32位汇编使用EAX,EBX,ECX,EDX寄存器,但是兼容16位的寄存器,即对应AX,BX,CX,DX,AL,BL,CL,DL,AH,BH,CH,DH.

比如说,当你想改变EAX的低8个bit时,只需要改变AL就可以.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值