高级语言源程序编译后产生的地址是逻辑地址还是物理地址

高级语言源程序编译后产生的地址是逻辑地址还是物理地址,第1张

由于 *** 作系统技术的发展,可重用二进制程序技术使用了内存重定位技术,所以从汇编的角度来看即不是逻辑地址也不是物理地址。而且这个概念有些不同,编译后产生的地址是相对地址,是相对于可执行头部位置的地址。而逻辑地址是指在指令系统内部使用的用来访问内存的一个逻辑表示,通常表现为相对于某个段基地址的偏移量。

当可执行程序被载入内存之后,才会有逻辑地址存在,此时可执行程序被如何加载于何处,地址为多少,由 *** 作系统决定,此时cpu访问程序用的是逻辑地址。一个程序一旦被编译确定之后基本上变量初始化的顺序固定,资源分配位置也固定,设置有编译器使用预分配机制,然后采用相对地址引用。

注意:某些工具书也称二进制可执行文件内所有的相对地址范围是逻辑地址空间,相对地址就是逻辑地址。因为两者的访问方式相似,逻辑地址变换依赖cpu或者附加变换机构(硬件),而二进制程序地址空间变换需要 *** 作系统插手管理。

反汇编分析中常常将二进制内部地址称为逻辑地址,因为反汇编器不能还原原来汇编代码的地址跳转空间特性,因此得到一个相对于二进制数据起点位置的相对地址,而和内存和物理存储都没有关系。

这个结构体是一个4字节 位结构体。冒号表示的是位域的意思,即访问当前变量名时访问的是本结构体的哪几位。

Uint16 rsvd1:3; // 2:0 reserved

定义的是使用结构体访问rsvd1这个成员变量时所返回的值由整个4字节结构体的0:2位组成;你这个结构体定义了一个CPU的32位状态寄存器各个位分别代表了什么含义,rsvd1表示前三位预留以后用;

结构体将cpu的32位分别映射为一个位域结构体,相对于移位 *** 作,该结构体方便程序访问寄存器的各个位;

用C51编程不需要定义地址,只要在interrupt 后面加上一个中断号“1”就表示是定时器0的中断服务程序。例程如下:

#include <REG51H>

void main(void)

{ EA = 1; // 允许中断

TMOD = 0x01;// 设定时器0为模式1(16位)

ET0 = 1; // 定时器0中断允许

TH0 = 0xee;// 晶振110592MHz,5mS

TL0 = 0;

TR0 = 1;// 开始计数

while(1);// 死循环,等待中断

}

void timeint(void) interrupt 1 // 定时器0中断服务程序

{ TH0 = 0xee; // 设置定时器时间常数 5mS中断一次

TL0 = 0;

}

in是输入型,调用该子程序时,必须对其赋值。out是输出型,子程序 *** 作的结果通过它传给外部变量。in-out是输入输出型。它们都是子程序的接口。定义完以后,调用子程序时可以看见相应的管脚。temp是子程序内部变量,旨在子程序内部使用,不与外部变量打交道。

解答:用16位移位寄存器扩展IO口,然后用扩展口来单独点亮LED, 这并不需要定义它的程序地址。

使用方法如下:如果你是一块16位移位寄存器控制16个灯,你的一个IO口只需输出两个字节(比如0X0001),这样就输出了0000 0000 0000 0001; 如果是2快16位移位寄存器级联,一个IO口输出4个字节接可以控制(比如先后输出0X00AA,0X0077),这样第一快芯片输出的是0000 0000 1010 1010 第二块芯片输出的是0000 0000 0111 0111;你级联几块芯片就要用一个IO口 多输出 16 位数据 让它流入下一级。

希望对你有启示作用,赞

先明白定义再说区别和原理: 1、程序存储器(program storage) 在计算机的主存储器中专门用来存放程序、子程序的一个区域。 2、指令寄存器(IR ):用来保存当前正在执行的一条指令。当执行一条指令时,先把它从内存取到数据寄存器(DR)中,然后再传送至IR。指令划分为 *** 作码和地址码字段,由二进制数字组成。为了执行任何给定的指令,必须对 *** 作码进行测试,以便识别所要求的 *** 作。指令译码器就是做这项工作的。指令寄存器中 *** 作码字段的输出就是指令译码器的输入。 *** 作码一经译码后,即可向 *** 作控制器发出具体 *** 作的特定信号。 3、程序计数器(PC):为了保证程序(在 *** 作系统中理解为进程)能够连续地执行下去,CPU必须具有某些手段来确定下一条指令的地址。而程序计数器正是起到这种作用,所以通常又称为指令计数器。在程序开始执行前,必须将它的起始地址,即程序的一条指令所在的内存单元地址送入PC,因此程序计数器(PC)的内容即是从内存提取的第一条指令的地址。当执行指令时,CPU将自动修改PC的内容,即每执行一条指令PC增加一个量,这个量等于指令所含的字节数,以便使其保持的总是将要执行的下一条指令的地址。由于大多数指令都是按顺序来执行的,所以修改的过程通常只是简单的对PC加1。 当程序转移时,转移指令执行的最终结果就是要改变PC的值,此PC值就是转去的地址,以此实现转移。有些机器中也称PC为指令指针IP(Instruction Pointer) 4、地址寄存器:用来保存当前CPU所访问的内存单元的地址。由于在内存和CPU之间存在着 *** 作速度上的差别,所以必须使用地址寄存器来保持地址信息,直到内存的读/写 *** 作完成为止 。 当CPU和内存进行信息交换,即CPU向内存存/取数据时,或者CPU从内存中读出指令时,都要使用地址寄存器和数据缓冲寄存器。同样,如果我们把外围设备的设备地址作为像内存的地址单元那样来看待,那么,当CPU和外围设备交换信息时,我们同样使用 地址寄存器和数据缓冲寄存器 基本上定义就是区别和应用。 蓝屏

C语言用变量来存储数据,用函数来定义一段可以重复使用的代码,它们最终都要放到内存中才能供 CPU 使用。

数据和代码都以二进制的形式存储在内存中,计算机无法从格式上区分某块内存到底存储的是数据还是代码。当程序被加载到内存后, *** 作系统会给不同的内存块指定不同的权限,拥有读取和执行权限的内存块就是代码,而拥有读取和写入权限(也可能只有读取权限)的内存块就是数据。

CPU 只能通过地址来取得内存中的代码和数据,程序在执行过程中会告知 CPU 要执行的代码以及要读写的数据的地址。如果程序不小心出错,或者开发者有意为之,在 CPU 要写入数据时给它一个代码区域的地址,就会发生内存访问错误。这种内存访问错误会被硬件和 *** 作系统拦截,强制程序崩溃,程序员没有挽救的机会。

CPU 访问内存时需要的是地址,而不是变量名和函数名!变量名和函数名只是地址的一种助记符,当源文件被编译和链接成可执行程序后,它们都会被替换成地址。编译和链接过程的一项重要任务就是找到这些名称所对应的地址。

假设变量 a、b、c 在内存中的地址分别是 0X1000、0X2000、0X3000,那么加法运算c = a + b;将会被转换成类似下面的形式:

0X3000 = (0X1000) + (0X2000);

( )表示取值 *** 作,整个表达式的意思是,取出地址 0X1000 和 0X2000 上的值,将它们相加,把相加的结果赋值给地址为 0X3000 的内存

变量名和函数名为我们提供了方便,让我们在编写代码的过程中可以使用易于阅读和理解的英文字符串,不用直接面对二进制地址,那场景简直让人崩溃。

需要注意的是,虽然变量名、函数名、字符串名和数组名在本质上是一样的,它们都是地址的助记符,但在编写代码的过程中,我们认为变量名表示的是数据本身,而函数名、字符串名和数组名表示的是代码块或数据块的首地址。

以上就是关于高级语言源程序编译后产生的地址是逻辑地址还是物理地址全部的内容,包括:高级语言源程序编译后产生的地址是逻辑地址还是物理地址、DSP里的地址定义问题:、单片机中的地址怎样定义比如说用C语言中断写的时钟程序要定义地址吗等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/10215959.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-06
下一篇 2023-05-06

发表评论

登录后才能评论

评论列表(0条)

保存