真值和机器数-整数的编码:

测试程序:

image.png

编译执行:

image.png

bi和cu输出的结果和预期的结果不一样的原因寻找:

1.反汇编并查看上面的可执行文件:

image.png
image.png
image.png从上图可以看出不敢是int的-100还是unsigned的-100其机器数都是用补码表示的。

调试程序:

image.pngs选项输出的是下一条要执行的语句,并且已经执行了。

原因:

bi=2147483648是int数据,它的机器数是0x80000000,当bi当中有符号输出时,会将机器数当中补码转换为真值结果为-2147483648;cu=-100,以二进制补码储存,机器数是0xffffff9,当以无符号输出时,机器数被解释为正数其真值为4294967196.
image.png

真值和机器数-浮点数的编码:

相关知识:

image.png
image.png

测试程序:

image.png

调试运行程序:

image.png
image.png
image.png
image.png
这里的0x56557028的由来:由汇编指令:image.png求出数值100浮点数的位置为:
%ebx-0x1fb0= 0x56558fd8-0x1fb0

数据存储的宽度和排列方式:

相关知识点:

image.png
image.png
image.png
image.png

测试程序:

image.png

编译运行:

image.png

调试:

image.pngimage.png上图的黄色的部分分别是a,bimage.png上图中黄色的部分是存储int d = 0x12345678,可以清楚的看出是小段方式
image.png这里也可以看出是小段方式

数据存储的对齐方式:

相关知识:

image.png
image.png
image.png
image.png

测试程序:

image.png

编译运行:

image.png

调试:

image.pngimage.png
image.pngimage.png(对照上图)
image.png
image.png

总结:

image.pngimage.png
image.png

整数之间数据类型的转换:

相关知识:

image.png
image.png
image.png
image.png

测试程序:

#include “stdio.h”
void main()
{
short si = -100;
unsigned short usi = si;
int i =usi;
unsigned ui = usi;
int i1 = si;
unsigned ui1 = si;
int i2 = 0x12348765;
short si2 = i2;
unsigned short usi2 = i2;
int i3 = si2;
int i4 = 4294967296;
printf(“si=%d,usi=%u,i=%d,ui=%u,i1=%d,ui1=%u\n”, si, usi, i, ui, i1, ui1);
printf(“i2=%d,si2=%d,usi2=%u,i3=%d,i4=%d\n”, i2, si2, usi2, i3, i4);
}

编译运行:

image.png

调试:

部分反汇编内容:
image.png
image.png(图1)
image.png(对照上图1理解这个赋值语句)
image.png(图中的si,usi在栈的内容可以结合反汇编内容计算出来)
image.png这里直接复制,不扩展和阶段,si和usi的机器数一样,但是真值根据数据类型不一样。
对照上图1理解:
int i = usi; unsigned ui = usi;
image.png
image.pngimage.png
理解int i1 = si; unsigned ui1=si;
image.png
image.pngimage.png
理解int i2 = 0x12345678;short si2 = i2;unsigend usi2 = i2;
image.pngimage.png
image.pngimage.png
理解 short si2 = i2;int i3 =si2;image.pngimage.png
理解int i4 = i4 = 4294967296;输出的值为0;
image.png

总结:

image.pngimage.pngimage.png
image.png

整数和浮点数之间的数据转换:

相关知识:

image.pngimage.pngimage.png
image.png
image.png
image.png

测试程序:

#include “stdio.h”
int main()
{
int i1 = 0x7fffffff, i2, itemp;
float f1 = 0x987654321, f2, ftemp;
ftemp = i1;
i2 = ftemp; //i2=(int)(float)i1;
itemp = f1;
f2 = itemp; //f2=(float)(int)f1;
printf(“i1=%d,i2=%d,f1=%f,f2=%f\n”, i1, i2, f1, f2);
}

编译运行:

image.png

调试:

部分反汇编内容:image.pngimage.pngimage.png
原因:
image.png
上图的加1操作是浮点数的舍入操作;i2的机器数和i2不一样原因是转换的时候进入舍入操作中加了1近似处理;
理解f2=(float)(int)f1:
image.png
image.png

C语言自动类型转换:

相关知识:

image.png
image.png
image.pngimage.png

测试程序:

#include “stdio.h”
int f1( unsigned int n )
{
int sum = 1, power = 1;
int i;
for ( i = 0; i <= n - 1; i ++ )
{
power *= 2;
sum += power;
}
return sum;
}
int main()
{
int sum;
sum = f1(0);
printf(“sum=%d\n”, sum);
return 0;
}

编译运行:

image.png执行的时候陷入了死循环,没有输出结果一直执行。

调试探索陷入死循环的原因:

部分反汇编内容:
image.png
注意上面的jae是无符号比较,i和n-1比较的时候会自动转化为无符号比较,image.png
根据上面的反汇编内容,edx是n-1,eax是i;
image.pngjae的转义指令永远会执行,不会退出循环。

修改:

把无符号n修改为带符号n,修改后执行然后反汇编。image.png可以看出jg是有符号比较。
修改后运行:image.png