源于前几天想扩展51单片机的外部ROM,网上能搜索到的扩展方式都是将EA引脚接地,让MCU上电后从外部ROM开始执行。但查看芯片手册,明明说EA为高时,程序从片内ROM执行,当执行到0x1000时(标准51单片机),会跳转到片外ROM执行。按网上的做法,为了扩展个片外ROM,片内的基本ROM都不用了,有点浪费了,于是开始找资料如何从片内跳转到片外,期间学习到intel hex文件格式,因此在此记录一下备忘。
接下来是我的整理:
keil c创建的工程,经过编译连接生成一个hex文件,看名字总觉得是个16进制文件,凭感觉这个文件里至少包含指令啥的吧,那就用16进制文本编辑器打开看看是什么:
假设源码是这样的:
ORG 1000H
STAR:
MOV A,#0AAH
MOV P1,A
MOV A,#55H
MOV P1,A
SJMP STAR
END
经过编译后生成hex,参考了intel汇编指令的编码,mov a,#0aah应该被编译成74AA,查看一下hex中有没有这段内容
16进制部分,完全没找到74AA这段内容,再看下MOV A,#55H对应的代码7455,也没找到!我擦,不能吧,没这些内容,mcu怎么执行?难道怀疑intel指令不对?人家大业大我们哪有资格怀疑,还是从自身检查起吧。
第一个连接的结尾部分(这么重要的内容作者你居然放最后,够了!)提到:
"hex文件是用ASCII来表示二进制的数值,例如一个8bit的二进制数值0x3F,用ASCII来表示就需要分别表示为字符‘3’和字符‘F’,每个字符需要一个Byte,所以hex文件需要2倍的空间"
意思是,hex文件本身存放的内容全是可见字符ASCII,这些ascii码中的0-9,A-F对应了16进制中的各个数字;一个字节包含两个16进制数,因此,需要hex文件中的两个字节的ascii码表示一个字节机器码。
回到上图,来到偏移0x11-0x14处,37 34 35 35这四个ascii码对应的字符是7455,好像就是MOV A,#55H的编码,再到偏移0x9-0x0c处37 34 41 41这四个ascii码对应了74AA,正好是mov a,#0AAH。好吧,好像有这么回事了,再试试其他指令,P1口的地址是90H,偏移0x0d-0x11之间的46 35 39 30对应F590 正好是MOV P1,A的编码。终于能解释的通去哪找指令了----用winhex最右边的可见字符部分查看指令编码。