1.扭扭捏捏,准备工作都是一大堆,要不来点汇编开开胃

/**   Register usage:**  s0  link versus load offset, used to relocate absolute adresses.*   s1  free*   s2  memory size.*   s3  free.*  s4  Bonito base address.*   s5  dbg.*   s6  sdCfg.* s7  rasave.*    s8  L3 Cache size.*/.set    noreorder.globl _start.globl    start.globl __main
_start:
start:.globl    stack
stack = start - 0x4000     /* Place PMON stack below PMON start in RAM *//* NOTE!! Not more that 16 instructions here!!! Right now it's FULL! */.set  push.set    mips64mfc0  t0, $16, 6or    t0, 0x100 xori  t0, 0x100       /*先或再异或,清零第8位*/mtc0  t0, $16, 6/* no sw combine */mfc0    t0, $16,  6ori     t0, 0x200       /*第九位置1*/mtc0    t0, $16,  6mfc0    t0, $22lui  t1, 0x0000//lui t1, 0x8000or    t0, t1, t0        /*或操作一个0,没意义呀 */mtc0   t0, $22.set popmtc0 zero, COP_0_STATUS_REG   /*清零COP_0_STATUS_REG 寄存器*/mtc0 zero, COP_0_CAUSE_REG    /*清零COP_0_CAUSE_REG 寄存器*/li    t0, SR_BOOT_EXC_VEC /* Exception to Boostrap Location  异常向量表*/   //[22]置1mtc0   t0, COP_0_STATUS_REG   /* 将异常向量表写入寄存器 */  //例外向量入口地址启动,BEV置1,采用rom的异常入口la sp, stack               /* 设置堆栈寄存器 ,指向起始代码的下方(地址减小的方向) */la    gp, _gp                 /* 设置GP寄存器 */WatchDog_Close     /* 这是个宏定义,关闭看门狗 *//* spi speedup */li  t0, 0xbfe00220li  t1, 0x07sb  t1, 0x4(t0)/* locate 在下面,约423行的样子。 */bal locate          /* Get current execute address */ /* 跳转到locate ,返回(绝对)地址保存在al寄存器中 */nop

来了一段汇编,要能看懂汇编,还得学点汇编指令啊。

1.1首先,.开头的都是伪操作,应该用于提示编译器,后面的代码应该如何处理,或者一些声明。

至少你得知道,伪操作,一般不能翻译为一条机器指令,它用来控制编译器的一些行为吧。

比如.global   声明一个全局的名称,让这个名称在别的文件可以使用,相当于c的extern。因为汇编跟c不同,汇编文件中默认所有的名称只能在本文件中使用,(相当于加了static)。如果你要让这个标号全局可见,就必须使用global修饰一下。但这并不会产生机器指令(在最终的可以执行的bin文件中也不会占用任何字节空间),只是在编译的时候能够识别到这个标号而已啦。

前面我们讲过,_start,start是整个程序的入口,那肯定有别的文件(如ld.scripts)需要识别到这个标号,所以这个标号必然要用global修饰一下。

.set 的操作比较多,我也是网上抄一点吧。

.set mipsn。n是一个从0到5的数字,或是数字32或64。1到5,32或64使汇编器从源程序中的这一点开始接受相应ISA级别的指令。 .set mipsn 不仅影响允许使用那些指令,还影响到某些宏如何被扩展。 .set mips0保持原本的ISA级别:这个级别是您通过命令行选项选择的,或者是您的配置的默认值。您可以通过这个特性在32位汇编模式中使用r4000的指令。小心使用这个命令!

命令‘.set mips16’使汇编器进入MIPS 16模式,传统的汇编器不支持这个命令

伪操作 .set mips3 告诉汇编器下面的指令是MIPS IV(64位指令集,兼容32位指令)中的指令。

.set mipsn

n是一个从0到5的数字,或是数字32或64。1到5,32或64使汇编器从源程序中的这一点开始接受相应ISA级别的指令。 .set mipsn 不仅影响允许使用那些指令,还影响到某些宏如何被扩展。

.set mips0保持原本的ISA级别:这个级别是通过命令行选项选择的,或者是配置的默认值。可以通过这个特性在32位汇编模式中使用r4000的指令

.set mips1 下面的指令是R2000/R3000指令,即MIPS I指令集

.set mips2下面的指令是R6000指令,即MIPS II指令集,这个没有产品化的芯片,一般不要使用

.set mips3下面的指令是R4000指令,即MIPS III,第一个支持64位的指令集

.set mips4支持MIPS IV指令集,它是在MIPSIII的基础上增加了一些浮点指令

.set mips5支持MIPS V指令集,在MIPS IV上增加了SIMD指令

另外.set mips32/mips64支持MIPS32/MIPS64指令集

这个牵扯到MIPS的指令集标准历史,1998年MIPS Technologies从SGI公司分离出来之后发布的指令集标准,MIPS32是MIPS II的超集,MIPS64是MIPS IV的超集,还是得回去读“历史”

.set noreorder/reorder

默认汇编器处在reorder的模式下,该模式允许汇编器对指令进行重新排序,以避免流水线堵塞并获得更好的性能,在这种模式下,是不允许在代码中插入 nop指令的。反之,在noreorder模式下,指令的顺序不会被改变也不会对代码进行任何优化。这样做的优点是程序员可以完全控制代码的执行顺序,缺点是必须手工对指令排序,并在分支和加载指令的延迟槽中填上有用的指令或nop指令.比如:

.set noreorder

lw   t0, 0(a0)

nop        #加载指令延迟槽

sub  t0, 1

bne  t0, zero, loop

nop        #分支指令延迟槽

.set reorder

.set volatile/novolatile

处在volatile区的所有存取指令都不会被移动位置(特别是存取指令之间的相对位置)。这一点对访问内存映射设备的寄存器非常重要。因为对于外围设备而言,读写的次序十分重要。另外对读状态寄存器也非常重要。因为想得到的状态都是最新的。举例来说,如果下列代码没有使用.set volatile,那么汇编器很有可能会对第二个lw指令移到指令的前面,因为这样可以填充第一条lw指令的延迟槽:

.set volatile

lw   t0, 0(a0)

sw   t0, 0(a1)

lw   t0, 4(a0)

.set novalatile

避免流水线堵塞的操作以及其他各种优化措施不受该设定的影响.

noat, nomacro, noreorder: 汇编语言控制操作,为程序员提供了一种方式来关闭汇编器做的一些更复杂的工作,这些工作不总是受欢迎的(相应的没有“no”的名字将该特性重新打开)

.set noat 阻止汇编器将汇编代码翻译成二进制序列依赖at/$1寄存器

.set nomacro 阻止汇编器将一条汇编代码翻译成多条指令

.set noreorder 阻止汇编器调整代码序列来将有用的指令放入分支延迟槽。

.set push --> save all settings (指的是什么设置???指的是现有的.set汇编指示环境)

.set reorder/noreorder --> let/don't let assembler reorder instructions

.set at/noat --> let/don't let assembler use the register $at in instruction aliases (li,la, etc.)

.set pop --> restore saved settings

1.2 用到得汇编指令:

mfc0 从协处理器0的寄存器中读出数据,f表示from

mtc0 把数据写入到协处理器0的寄存器中,t表示to

or 或运算 ,跟c语言按位或运算一致

xori  xor表示异或,与c一致,i表示立即数,表示这个操作是与一个数字进行的。

ori 立即数的或运算

lui 加载立即数到高16位,u表示高16位uper,l表示加载(load),从内存读数据到寄存器

li 加载立即数,这是条伪指令,汇编的时候可能需要根据情况自动转为其他指令

la 加载标号对应的地址,a表示address

sb s表示存储(store),表示是从寄存器写入到内存,b表示字节,表示该指令只操作一个字节

bal b表示跳转(branch),bal表示跳转的同时,保存返回地址到ra寄存器。跳出去还可以回来。

上述代码中用到的汇编稍微解释了一下,不懂的继续百度,或者加我qq166781997

1.3 上述代码做了什么?

1.3.1 协处理器0的寄存器需要参考手册《user2.pdf》

mfc0    t0, $16, 6   ,表示从寄存器16读取数据到t0寄存器,后面的数字6,表示第6个 选择寄存器。

这里考虑到的是兼容性问题,当初没有设计那么多协处理器寄存器,但是后来又需要跟多,为了与之前的兼容,做了select这样的设计。

结合后面的语句,或操作,然后异或,那就是要清零寄存器中第8位,然后把这个值写进去。

好,这四句就是关闭这个自动写合并功能。(具体是啥,以后再琢磨吧。)

1.3.2 接下来3句

mfc0    t0, $16,  6
    ori     t0, 0x200        /*第九位置1*/
    mtc0    t0, $16,  6

置1第9位,看pdf:

文档说必须写,那就写吧,这还能咋样???

1.3.3接下来4句

mfc0    t0, $22    //这条是访问寄存器22,后面没有数字,表示select 0
    lui    t1, 0x0000
    //lui    t1, 0x8000
    or    t0, t1, t0        /*或操作一个0,没意义呀 */
    mtc0    t0, $22

似乎没得意义????高木及。。。。

1.3.5  接下来几句:

mtc0    zero, COP_0_STATUS_REG   /*清零COP_0_STATUS_REG 寄存器*/


    mtc0    zero, COP_0_CAUSE_REG    /*清零COP_0_CAUSE_REG 寄存器*/


    li    t0, SR_BOOT_EXC_VEC    /*0x40,0000*/   //[22]置1
    mtc0    t0, COP_0_STATUS_REG    //例外向量入口地址启动,BEV置1,采用rom的异常入口


    la    sp, stack                /* 设置堆栈寄存器 ,指向起始代码的下方(地址减小的方向) */
    la    gp, _gp                    /* 设置GP寄存器 */

1.3.6 最后几句吧

WatchDog_Close     /* 这是个宏定义,关闭看门狗 */

#define WatchDog_Close \
GPIO_CLEAR_OUTPUT(0x1<<5); \
GPIO_SET_OUTPUT(0x1<<3|0x1<<4); \
GPIO_CLEAR_OUTPUT(0x1<<13); \

/* spi speedup */
    li  t0, 0xbfe00220
    li  t1, 0x07
    sb  t1, 0x4(t0)

bal    locate            /* Get current execute address */ /* 跳转到locate ,返回(绝对)地址保存在al寄存器中 */
    nop

1.4 做了什么?

1.做了一些清理工作,处理器模式,中断这些都清除掉,中断入口应该设置位rom,现在程序还在rom里面。

2.关闭看门狗

3.sp寄存器,和gp寄存器设置好了,但是sp应该还不能用(ddr没有初始化)。跳到下一个函数继续初始化。

在这里我们也看到,修改一个寄存器的基本步骤,是读出这个寄存器的值,通过位操作修改这个值(只改变你需要改变的位),然后把这个值再写入到寄存器。

这是嵌入式开发的常用操作。

单龙芯3A3000-7A1000PMON研究学习-(15)撸起袖子干-先来一杯代码吧相关推荐

  1. 单龙芯3A3000-7A1000PMON研究学习-(14)撸起袖子干-分析代码前的准备工作2

    1.我细细回想一下,感觉要准备的东西很多. 比如体系结构,汇编指令,地址映射,外设.... 然而,光体系结构就复杂到要用n页(官方的)pdf才能说清楚(其实不一定能说清楚,可能还得慢慢去琢磨).这里还 ...

  2. come type6 定义_COMe-B6101龙芯3A3000 COM Express Type6模块

    COMe-B6101是一款以龙芯3A多核处理器和AMD RS780E SB710芯片组为核心,高可靠性和高效能的主板模块.COMe-B6101 内部集成ATI M72-based图像引擎,支持双屏显示 ...

  3. 单龙芯3A3000-7A1000PMON研究学习-(16)撸起袖子干-分析代码前的准备工作3-寄存器

    1.这篇还是稍微介绍一下cpu相关的寄存器. 手册里面说到的寄存器分两种,一种是cpu使用的(汇编中用来存放数据的),另一种是外部设备寄存器(一般用于配置功能,或者读写外部设备数据用的.),在手册中都 ...

  4. 【保姆级教程】在龙芯3A5000上编译arrow-0.15.1

    环境信息 处理器:龙芯3C5000 操作系统:Loongnix Server 8.4.1 内核版本:4.19.190-6.5 1.arrow-0.15.1的编译参数 每家的参数不一样,可以根据自己需求 ...

  5. 龙梦拿下3万片大单 龙芯电脑年底量产无悬疑

    10月9日,龙芯有关人士通过搜狐博客透露,"龙梦电脑已经有人拿到货,批量生产在11月15日以后,因为量产的芯片11月15日才到."这与龙梦科技此前关于"龙芯电脑年底量产& ...

  6. 单龙芯3A3000-7A1000PMON研究学习-(19)撸起袖子干-再来一杯代码3

    1.start.S包含一个独立的pcitlb.S文件 ##########################################     PRINTSTR("NO TLB cach ...

  7. 单龙芯3A3000-7A1000PMON研究学习-(8)撸起袖子干-make tgt=rom初步分析(a)

    1.make tgt=rom 开始编译了. 在zloader.3a3000_7a目录下的Makefile.inc,指定了我们要的目标. tgt = rom. 所以就是执行73行的rom这个目标. 这里 ...

  8. 单龙芯3A3000-7A1000PMON研究学习-(11)撸起袖子干-make tgt=rom的编译过程

    1. 今天来分析一下makefile,看看如何编译出执行文件pmon的. 先贴几张图,makefile的内容,这是一些依赖关系 图一 图二 图三 图四 图五 2.图一解释 rom这个目标又三个依赖,c ...

  9. 单龙芯3A3000-7A1000PMON研究学习-(12)撸起袖子干-分析代码前的准备工作1

    1.make的过程我说了个大概,大家可以参考一下前面的文章.现在准备分析代码吧,其实这个准备工作内容应该蛮多的.可能后面还要补充. 2.首先找到关键的bin文件啊,就是可以最终下载到flash,能启动 ...

  10. 走进龙芯3A3000(四)安装XFCE4

    我想要安装KDE 我想要qtwebengine的MIPS64实现.曾经读过千里孤坟的<KDE综览>,就深深喜欢上了KDE,当时的版本还是KDE3.后来KDE4发布,千里孤坟又写了<K ...

最新文章

  1. puppet原理及配置
  2. oracle控制文件的损坏或完全丢失的恢复办法
  3. c include 多层目录_Rsync 秒杀一切备份工具,你能手动屏蔽某些目录吗?
  4. 理解总结篇—List、Set、Map
  5. 蒙特卡洛法求圆周率 c语言,c++蒙特卡洛法求圆周率
  6. 解决IDEA运行Flink报错java.lang.NoClassDefFoundError: org/apache/flink/api/common/ExecutionConfig....
  7. Python简洁的出入库系统(模块化)
  8. docker 时区_centos7.X上部署docker并运行常用的应用
  9. C++ 将模板申明为友元
  10. 介绍几款高级DAC解码芯片(整编)
  11. 2012年度总结:内心宁静的2012
  12. 《英语语法新思维初级教程》学习笔记(五)形容词
  13. 教你们如何快速建立一个完美的python项目
  14. 南开大学计算机本科论文,南开大学本科(论文)模板.doc
  15. 用python3实现HDU爬虫(后续可能更新VJ)2016.11.4更新
  16. 自我管理数据缓冲区内存
  17. Java虚拟机规范 Java SE 8版 - class文件格式(二)
  18. 闭关修炼(八)反射机制
  19. 某微型计算机标明piv 1.8g,计算机必备.doc
  20. 网络安全 社会工程学--钓鱼网站的制作和利用(让你了解整个钓鱼网站 背后的秘密.)

热门文章

  1. 腾讯云cdn设置 php,腾讯云免费CDN开通及接入教程
  2. 如何快速开通微信商户现金红包
  3. 爱五笔iWuBi for mac(好用的五笔学习软件)
  4. SAP 与 3大财务报表
  5. mysql 登录 无密码_重置mysql的密码/无密码登录mysql
  6. 微积分 导数 微分 偏导数 方向导数 梯度 向量 雅克比矩阵 概念
  7. linux fifo文件,linux中的命名管道(FIFO)
  8. 用Bat文件创建桌面快捷方式
  9. matlab 无法保存.m文件
  10. 柔性制造物料抓取及加工系统设计