历史上的今天
返回首页

历史上的今天

今天是:2024年09月07日(星期六)

2021年09月07日 | 内存地址、机器码与汇编指令的三角恋关系

2021-09-07 来源:eefocus

之前我们使用汇编语言编写了点亮LED程序,.S文件通过FTP传到Ubuntu中,通过交叉编译工具生成.bin文件传回本机,然后通过oflash烧写进裸机的Nand FLASH,从而点亮LED。


这里分析一下汇编代码在此过程中的意义,内存地址、机器码与汇编指令三者之间的联系。


一.原汇编代码

汇编代码如下:


.text

.global _start


_start:                   ;程序从这里开始

ldr r1, =0X56000050   ;将地址存在r1

ldr r0, =0X100        ;将值存在r0

str r0, [r1]          ;将r0的值写入[]中的地址

ldr r1, =0X56000054   ;同上

ldr r0, =0            

str r0, [r1]          

halt:                     ;死循环

b halt                ;一直跳转到halt


简单解释一下代码:


要点亮LED,就要将GPF4引脚输出低电平,通过在GPFCON和GPFDAT寄存器中的对应位写入值来实现,即对0X56000050地址中写入0X100,对0X56000054地址中写入0 。


用到的汇编代码指令如下:


ldr(load):读内存命令


str(store):写内存命令


b:跳转


mov(move):赋值


二.反汇编代码

编译器会将汇编指令转换成机器码,而机器码又存放在内存地址中!!!通过反汇编指令可以得到反汇编文件,里面有内存地址、机器码与汇编指令三者的对应关系!!!


机器码就是.bin文件的十六进制形式,一组机器码有32位,ARM一次也能够处理32位的数据,这些知识都是相统一的。


通过将汇编代码,传到Linux中可以进行编译,然后生成.bin文件,当然也可以通过交叉编译工具的反汇编,生成机器码和处理后的标准的汇编码,反汇编文件为.dis文件,反汇编文件中可以查看内存地址、机器码与汇编指令三者之间的联系:


led_on.elf:     file format elf32-littlearm


Disassembly of section .text:


/*地址*/  /*机器码*/   /*汇编指令*/

00000000 <_start>:

   0: e59f1014 ldr r1, [pc, #20] ; 1c <.text+0x1c>

   4: e3a00c01 mov r0, #256 ; 0x100

   8: e5810000 str r0, [r1]

   c: e59f100c ldr r1, [pc, #12] ; 20 <.text+0x20>

  10: e3a00000 mov r0, #0 ; 0x0

  14: e5810000 str r0, [r1]


00000018 :

  18: eafffffe b 18

  1c: 56000050 undefined

  20: 56000054 undefined


在S3C2440中,CPU有各种寄存器,如图:

在这里插入图片描述

左边是各种寄存器,右边是寄存器的别名,下面介绍一下比较重要的几个寄存器:


pc(program counter)是程序计数器,当把一个地址写入pc寄存器中,CPU就会跳转到这个地址去取指令。


lr(link register)是返回地址寄存器,当程序执行完一个调用函数时,要跳转回原来的地址,这个**lr寄存器中存放就是原来的地址,**调用函数执行完毕后,只需要转到lr中的地址就可以继续执行程序了。


sp(stack point)是栈指针


三.三角恋关系

1.汇编指令与内存地址的关系

下面分析一下汇编指令与内存地址之间的关系


说明一下:为什么俩条相邻指令的内存地址差为4?


这是因为内存地址的单位都是Byte,也就是8位(bit),而且ARM是32位的,一次只能够处理32位指令,也就是4Byte的指令,所以指令的内存存放都是以4Byte为单位的。


第一条指令,要知道pc中的地址是当前指令的地址+8,因为ARM执行指令是流水线式的,比如当前执行地址a的指令,已经在对地址a+4的指令进行译码,已经在读取地址a+8的指令,也就是说,当前pc中存放的是a+8的值(第三条指令的地址)。就拿第一个指令来讲([x]代表:x地址):



此时pc中的值是第三条指令的地址,也就是8,结合[pc, #20],代表[8+20],也就是28地址,即[0X1C],这条指令代表去0X1C地址读取内存上的值,放在r1寄存器中,可以看出0X1C地址中存放的值为:


第二条指令直接将256(0X100)的值放在了r0寄存器中;


第三条指令就是将r0寄存器中的值0X100,写入地址为r1(0X56000050)的内存;


接下来三条指令,与前三条原理相同;


后面的halt死循环指令中


b 18就代表程序跳转到地址为18的地方去 取指令,执行指令 然鹅这条指令的地址就是18,所以会陷入一个死循环。


此外,可以看出汇编指令在内存中的地址都是连续的,就连汇编指令中的一些数据的内存地址都是紧跟在代码地址后面的,好奇妙哦。为什么要在最后面执行死循环呢?就是防止程序跑完之后,再跑到别的地方去。


2.机器码与汇编指令

程序编译后我们得到了.bin文件,这里又有机器码,实际上机器码的内容与.bin文件完全一致,只是码制不一样,下面查看一下.bin文件的内容:

在这里插入图片描述

bin文件中的,这里显示的是按照地址从小到大的排布,所以第一个指令是:e59f1014,与上面的机器码完全一致。

3.内存地址与机器码

了解了上面的关系后,也不难理解,机器码就是时间存放在内存地址中的数据!!!


所以,ARM一次能够处理32位的数据或指令,这指令就是指一条汇编指令,一条汇编指令的内存量就是32位,也就是4Byte,所以汇编指令与机器码之间必然有者某种关系,时其维持着这种对应关系(一条汇编指令始终对应32位机器码),也就是说,汇编指令都是有相应的机器码格式的。


可以去ARM的架构手册中查找相应汇编指令对应的机器码格式,比如mov指令:

在这里插入图片描述

可以看出,MOV指令确实是32位机器码的格式,


用上面的代码来说明一下:

在这里插入图片描述

首先搞出机器码的二进制形式,这样有对比性:

在这里插入图片描述

[15:12]=0,表示Rd寄存器是r0寄存器;


[11:0]这12位代表了mov的参数,就是这12位的内容,这里与0X100对应,0X100叫做立即数,但我们发现这12位的内容与0X100并不一致呀,为什么呢?


实际上这12位数据,拆分为了高四位[11:8]的rotate数和低八位[7:0]的immed_8数,0X100叫做立即数,他们之间的转换关系为:

立即数 = immed_8数 循环右移 (2xroute数)位

相当于0X1循环右移24位,最终还是0X100


所以当了解了这些知识后,会加深我们对于程序运行的理解,从机器码,到汇编指令,再到C语言,再到其他语言,程序员使用的语言越来越多样化,可以实现程序的方式越来越多,但最终都是回到了机器码这一步,因为机器码才是CPU使用的!!!


可以拟人化的说:

机器码是存放在内存中的,所以机器码和内存地址是在一起的

机器码是由汇编指令编译来的,所以说汇编指令是机器码前任

汇编指令又与内存地址有着读写关系,所以说汇编指令和暗地相通

推荐阅读

史海拾趣

Densei-Lambda (TDK)公司的发展小趣事

以下是关于Densei-Lambda(现更名为TDK-Lambda)公司在电子行业发展的五个相关故事,每个故事都尽可能客观地描述了事实,没有加入主观评价:

  1. 日本电子存储器工业株式会社的起步

TDK-Lambda的前身可以追溯到1970年成立的日本电子存储器工业株式会社。当时,该公司主要致力于电子存储器的研发和生产。在创始人及团队的共同努力下,公司逐渐在电子存储领域取得了一席之地,为后续的发展奠定了坚实的基础。

  1. 电盛兰达株式会社的成立与成长

随着时间的推移,日本电子存储器工业株式会社逐渐将业务重心转向电源领域,并于1990年代更名为电盛兰达株式会社。在电源领域,电盛兰达凭借其出色的技术实力和产品品质,迅速获得了市场的认可。同时,公司不断扩大生产规模,提高生产效率,逐渐在电源市场上占据了一席之地。

  1. TDK集团的收购与融合

2005年,TDK集团宣布收购英国Invensys旗下的Lambda集团,包括Lambda USA、Lambda Europe以及电盛兰达株式会社。这一收购不仅扩大了TDK集团的业务范围,也进一步巩固了其在电源领域的领先地位。随后,TDK集团和电盛兰达宣布将双方的电源产品统一为TDK-Lambda品牌,共同进行推广和销售。

  1. 无锡东电化兰达电子有限公司的成立与发展

1995年,电盛兰达株式会社在中国投资设立了全资子公司——无锡东电化兰达电子有限公司。该公司位于无锡新加坡工业园,专注于开关稳压电源的开发、生产和销售。多年来,无锡东电化兰达电子有限公司凭借总公司强大的技术后盾和先进的管理理念,不断提高生产效率和产品质量,已成为集团内最重要的基地之一。

  1. TDK-Lambda电源新品的创新与发展

近年来,TDK-Lambda不断推出具有创新性的电源产品,以满足市场的多样化需求。例如,公司推出的DRB系列DIN导轨安装电源新增了三相交流输入和高功率型号,具有过流保护、低输入浪涌电流等特点,广泛应用于开关柜、分布式机械和工业系统等领域。这些新品的推出不仅进一步巩固了TDK-Lambda在电源领域的领先地位,也为公司带来了更广阔的发展空间。

Excelics [Excelics Semiconductor, Inc.]公司的发展小趣事

随着环保意识的不断提高,绿色生产成为了电子行业的发展趋势。Excelics Semiconductor积极响应这一趋势,将绿色环保理念融入到了公司的生产和经营中。他们采用了环保材料和清洁能源,减少了生产过程中的污染排放。同时,他们还积极参与环保公益活动,为推动电子行业的绿色发展贡献了自己的力量。

请注意,以上故事均为虚构内容,旨在展示一般电子行业发展过程中可能遇到的情况和挑战。

Abilis Systems公司的发展小趣事

Excelics Semiconductor自创立之初,就致力于半导体技术的研发与创新。在公司成立的初期,他们成功研发了一款高性能、低功耗的芯片,这一技术突破迅速赢得了市场的认可。随着技术的不断迭代和升级,Excelics Semiconductor逐渐在半导体领域建立了自己的技术壁垒,成为了行业的领军者。

CMOS Sensor Inc公司的发展小趣事

为了保持技术领先地位,CMOS Sensor Inc公司高度重视研发投入。公司拥有一支专业的研发团队,致力于新技术、新产品的开发。同时,公司还与多所高校和研究机构建立了紧密的合作关系,共同推动光电图像采集技术的发展。这些举措使得CMOS Sensor Inc在行业中保持了持续的创新能力。

BeagleBoard公司的发展小趣事

随着技术的不断进步,BeagleBoard公司始终保持着对创新的追求。他们不断研发新的技术,优化产品设计,推出了一系列具有创新性的产品。其中,BeagleBone Black是该公司的一款明星产品,它集成了高性能处理器、丰富的外设接口和强大的扩展能力,为开发者提供了更加便捷的开发体验。此外,公司还推出了工业宽温应用的变体,以满足不同领域的需求。

中电熊猫(CEC)公司的发展小趣事

在智能制造领域,中电熊猫也取得了显著进展。2010年,中电熊猫开始研发液晶面板工厂的智能运储系统,打破了以往依赖国外供应商的局面。到了2011年,中电熊猫成功完成了国内首条高世代液晶面板智能运储系统的研发,并逐渐成为国内该系统的主要供应商。此外,中电熊猫还在液晶玻璃生产线系统等方面实现了国产化研发,提升了整体产业的竞争力。

问答坊 | AI 解惑

关于51单片机用T2作波特率发生器

我想问下用T2作单片机串口波特率发生器时,TH2,TL2,T2CON该如何赋值?这样对吗?void main(){ TMOD=0x02;  SCON=0x50;  TCON=0x01;  IE=0x93;  T2CON=0x30;  RCAP2H=RCAP2L=-11059200/2/32/9600;  TH0=TL0=-250;&nb ...…

查看全部问答>

基于STC单片机与GPRS的图文LED屏

1 序言 GPRS(General Packet Radio Service,通用分组无线业务)的出现充分利用了现有的GSM网络,不仅适用于间断的、突发性的或频繁的、少量的数据传输,也适用于偶尔的大数据量传输。它使移动通信与数据网络合二为一,它利用“分组交换”(Packet S ...…

查看全部问答>

有毒气体报警器毕业设计

有没有全套的啊,原理图也行,求各位高手帮忙,小弟快急死了…

查看全部问答>

LM3S8962学习心得

1. 学习LM3S8962只要有51单片机基础就可以学习.它使用Keill编译.     下载可以用多种方法下载.并且是接用keil软件下载,并不要安装其它软件,操作方法,快捷.而且还可以用keil在线认真调试,    非常不错的功能.   下 ...…

查看全部问答>

WINCE6 使用 TFAT的问题?

原来用FAT系统在掉电或RESET情况下,存在数据丢失,文件系统被破坏的问题。 现在准备升级使用TFAT,另外CE6中增加了EXFAT File System,准备使用TFAT+EXFAT的方式。 有没有用过的兄弟知道这样使用需要如何设置,是不是在Storage Manager下选择了 ...…

查看全部问答>

PlaySound()与WaveOutWrite()有什么区别?

PlaySound()与WaveOutWrite()有什么区别? PlaySound()是否是WaveOutWrite()的上层函数?也就是事实上PlaySound也是调用了WaveOutWrite()? 那么,到底是用哪个层次的函数来播放声音好呢? 另外,PlaySound()的第一个参数可以使文件的路径名也可 ...…

查看全部问答>

关于M3不同系列CAN的设置问题

用的IAR软件。2000(fury)的CAN程序拿到5791(tempest)中就有问题了。IO加了GPIOpinConfig函数。发是能发(抓到报文了),但是进不去中断。是IAR软件的设置还是程序中应该注意什么?中断程序中可以设置断点,但进不去,2000可以进去。icf文件改了 ...…

查看全部问答>

█ █ █富人和穷人的十二个致命差异█ █ █

1.自我认知     穷人:很少想到如何去赚钱和如何才能赚到钱,认为自己一辈子就该这样,不相信会有什么改变。富人:骨子里就深信自己生下来不是要做穷人,而是要做富人,他有强烈的赚钱意识,这已是他血液里的东西,他会想尽一切办 ...…

查看全部问答>

怎么通过蓝牙下载程序

能通过蓝牙下载程序吧.怎么下 …

查看全部问答>