袁春风计算机组成原理1.1.1

组成原理笔记

在这里插入图片描述

Main.c
Int d=100;
Int x=200;
Int main()
{
P1();
Printf(“d=%d,x=%d\n”,d,x);
Return 0;
}
P1.c
Double d;
Void p1()
{
D=1.0;
}
打印结果是什么?
D=0, x=1 072 693 248
Why?
理解此问题需要知道:
机器级数据的表示
变量的存储空间分配
数据的大端小端模式
连接器的符号解析规则

/复制数组到堆中,count为数组元素个数/
Int copy_array(int array, int count){
Int I;
/在堆申请一块内存/
Int myarray=(int)malloc(count
sizeof(int));
If (myarray==NULL)
Return -1;
For(i=0;i<count;i++)
Myarray[i]=array[i];
Return count;
}
当count=2^30+1是,程序会发生什么情况?
当参数count很大时,则count*sizeof(int)会溢出,堆中大量数据会被破坏。

代码段一:
Int a=0x80000000;
Int b=a/-1;
Printf(“%d’,b);
运行结果为-2147483648

代码段二:
Int a=0x80000000;
Int b=-1;
Int c=a/b;
Printf(“%d\n”,c);
运行结果为”Floating point exception”, 显然CPU检测出了异常。

为什么两者结果不同?
用反汇编代码得知除以代码一-1被优化成取负指令neg,故为发生除法溢出。
代码二:a/b用除法指令idiv实现,但他不生成of标准,那么如何判断溢出呢?实际上“除法错”异常#DE(类型0)Linux中,堆#DE类型法=发出SIGFPE信号。
理解这些问题需要知道:
编译器如何优化
机器级数据的表示
机器指令的含义和执行
计算机内部的运算电路
除法错异常的处理

以下是一点c语言代码:
#include<studio.h>
Main()
{
Double a=10;
Print(“a=%d\n”,a);
}
在IA-32运行时,打印结果a=0
在x85-64上运行时,打印结果:a时一个不确定值。
为什么??
理解贵问题需要知道:
IEEE 754 的表死
X87 FPU的体系结构
IA-32和x86-64中过程调用的参数传递
计算机内部运算电路……
Double fun (int i)
{
Volatile double d[1]={3.14};
Volatile long int a[2];
A[i]=1073741824; /Possibly out of bounds/
Return d[0];
}
Fun(0)—> 3.14
Fun(1)—>3.14
Fun(2)—>3.139999986664856
Fun(3)—>2.000000061035156
Fun(4)—>3.14,然后存储保护错
Why?
理解该问题需要知道:
机器级数据的表示
过程调用机制
栈中数据的布局
……

行优先和列优先
Void copyij(int src[2048][2048], Int dst[2048][2048])
{
Int I,j;
For(i=0;i<2048;i++)
For(j=0;j<2048;j++)
Ds[i][j]=src[i][j];
}
Void copyright (int src[2048][2048], int dst[2048][2048])
{
Int I,j;
For(j=0;j<2048;j++)
For (i=0;i<2048;i++)
Ds[i][j]=src[i][j];
}
以上两个程序功能完全一样,算法完全一样,因此时间复杂度和空间复杂度完全一样,执行时间一样吗?
理解该问题需要知道
数组的存放方式
Cache机制
访问局部性
……

使用老版本gcc-02编译时,程序一输出0,程序二输出1.
Why?
程序一:
#include<studio.h>
Double f(int x){
return 1.0/x;
}
void main(){
double a,b;
int i;
a=f(10);
b=f(10);
i=a==b;
printf(“%d\n”,i);
}
程序二
#include<studio.h>
double f(int x){
return 1.0/x;
}
void main()
{
double a,b,c;
int i;
a=f(10);
b=f(10);
c=f(10);
i=a= =b;
printf(“%d\n”,i);
}

网上一个分析
#include<stdafx.h>
int main(int argh,char*argv[])
{
int a=10;
double p=(double)&a;
printf(“%f\n”,*p); //结果为0.000000
printf(“%f\n”,(double(a)));//结果为10.000000

return 0;
}
为什么printf(“%f”,*p)和printf(“%f”,(double)a)结果不一样呢?
都是强制类型转换,为什么会不一样??
关键差别在一条指令:fldl和fildl
fldl指令表示把int数值直接当成浮点数进行打印,fildl表示int进行double转换。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值