一、mips架构通用寄存器命名

二、mips汇编指令操作

1、指令集

2、实例:

#example
.data
array1: .space 12         #  declare 12 bytes of storage        # to hold array of 3 integers
.text
__start:
la  $t0, array1              #  load base address of array       # into register
$t0  li  $t1, 5              #  $t1 = 5   ("load immediate")
sw  $t1, ($t0)              #  first array element set to 5# indirect addressing
li  $t1, 13                #   $t1 = 13
sw  $t1, 4($t0)           # second array element set to 13
li $t1, -7                 #   $t1 = -7
sw  $t1, 8($t0)            # third array element set to -7

start.s汇编分析

    mtc0 zero, CP0_WATCHLOmtc0 zero, CP0_WATCHHI                清除硬件数据断点,防止产生调试断点,导致程序停止。芯片在复位后,某些寄存器的内容也许是你想要的结果,但是谁知道呢,为了保证准确无误,最好还是重新进行手动初始化mfc0 k0, CP0_STATUSli  k1, ~ST0_IEand k0, k1mtc0 k0, CP0_STATUS                    禁止全局中断
    mtc0 zero, CP0_CAUSE                  初始化异常寄存器,清除异常原因指示mtc0 zero, CP0_COUNTmtc0 zero, CP0_COMPARE初始化时钟寄存器,防止产生计数器中断li t0, CONF_CM_UNCACHEDmtc0 t0, CP0_CONFIG设置kseg0区不经过cache。cache需要先初始化才能使用。bal 1fnop.word _gp
1:lw gp, 0(ra)bal分支调用,ra返回地址指向下下一条指令,即.word _gp把.word _gp的存储位置载入gp寄存器,即设置GOT表的起始位置la t9, lowlevel_initjalr t9nop根据CPU rate初始化外部时钟、内存。lowlevel_init函数定义见lowlevel_init.Sla t9, mips_cache_resetjalr t9nop初始化高速缓存cache。mips_cache_reset函数定义见cache.Sli t0, CONF_CM_CACHABLE_NONCOHERENTmtc0 t0, CP0_CONFIG设置kseg0区经过cacheli a0, CFG_INIT_SP_OFFSETla t9, mips_cache_lockjalr t9nopli t0, CFG_SDRAM_BASE + CFG_INIT_SP_OFFSETla sp, 0(t0)C语言程序(接下来的函数board_init_f)调用需要栈,而ram还没有初始化不能使用,所以用CACHE_LOCK_SIZE大小的L1 Dcache锁定作为临时栈使用以sp开始,CACHE_LOCK_SIZE大小的堆栈,使用D-cache临时替代la t9, board_init_f   初始化j t9nopboard_init_f函数定义见board
relocate_code:                 对应board.c里的relocate_code (addr_sp, id, addr),此时a0=addr_sp,a1=id,a3=addr。move sp, a0                设置新的sp = addr_spli t0, CFG_MONITOR_BASE      board/xxx/config.mk #define CFG_MONITOR_BASE TEXT_BASE  board/xxx/config.mk #define CFG_MONITOR_BASE TEXT_BASE
    la t3, in_ram                  t0 = uboot程序在flash的超始地址,t1 =  准备把uboot程序移到ram中的起始地址lw t2, -12(t3)                t2 = uboot程序的结束地址        move t1, a2move t6, gpsub gp, CFG_MONITOR_BASE     计算旧的gp与相对于TEXT_BASE的偏移   add gp, a2                    计算新的gp在移动目的地内存中的地址sub t6, gp, t6                t6 = 新gp(内存中)与旧gp(flash中)的地址偏移量,这个值也是整个uboot从flash移到内存的偏移量。等同于(Destination Address - CFG_MONITOR_BASE)
1:lw t3, 0(t0)sw t3, 0(t1)addu t0, 4ble t0, t2, 1baddu t1, 4按字拷贝,把uboot bin的内容从源地址(flash)拷贝到目的地址(内存),拷贝的长度是从uboot开始到uboot_end_data为止,uboot_end_data后面是bss段,详见uboot.ldsaddi t0, a2, in_ram - _startj t0nop计算in_ram在内存中的新地址保存到t0,然后跳转到内存中运行in_ram。从此开始,uboot的代码将在ram中运行了.gpword_GLOBAL_OFFSET_TABLE.word uboot_end_data.word uboot_end.word num_got_entries
in_ram:t3 = num_got_entries,t4 = 新的GOT[2]li t2, 2
1:lw t1, 0(t4)beqz t1, 2fadd t1, t6sw t1, 0(t4)
2:addi t2, 1blt t2, t3, 1baddi t4, 4这里是一个循环,从GOT[2]开始,判断如果GOT表项有内容,则把内容从旧的GOT表拷贝到新的GOT表里。为什么要做拷贝呢?上面的程序已经把uboot整个程序从flash拷贝到了ram里,注意,只是内容拷贝,GOT里的地址还是老地址,所以要做重定位(如果是静态编译且属于模块内相对偏移,就不需要这个步骤了)。手工重定位的方法就是把旧GOT里的内容读取,然后加上偏移(uboot在flash与ram的偏移)赋值给新GOT里的对应表项程序构建过程(编译和生成程序时的链接)为每个链接单元(构成动态链接程序的二进制文件,如.o、.a、.so)至少定义一个GOT,每个函数都可以找到自己的GOT,因为GOT的位置离链接单元的入口点的偏移量是固定已知的。链接单元作为一个整体载入内存,所以GOT的内部偏移量与编译时是一样的。u-boot在编译时使用-fpic,会生成一个.got段来存储绝对地址符号。lw t1, -12(t0)lw t2, -8(t0)add t1, t6add t2, t6sub t1, 4
1:addi t1, 4bltl t1, t2, 1bsw zero, 0(t1)t1 = uboot_end_data,      t2 = uboot_end进行BSS段的清零,此时还没有操作系统,动态链接器,加载器等这些东东都还没有,所以要手动执行清零move a0, a1la t9, board_init_rj t9move a1, a2跳转到ram中的board_init_r执行,根据MIPS ABI规范,a0、a1分别是board_init_r的第一个、第二个参数,即board_init_r (gd_t *id, ulong dest_addr)中id = a0,dest_addr = a2t0 = uboot程序在flash的超始地址,t1 =  准备把uboot程序移到ram中的起始地址lw t2, -12(t3)                t2 = uboot程序的结束地址        move t1, a2move t6, gpsub gp, CFG_MONITOR_BASE     计算旧的gp与相对于TEXT_BASE的偏移   add gp, a2                    计算新的gp在移动目的地内存中的地址sub t6, gp, t6                t6 = 新gp(内存中)与旧gp(flash中)的地址偏移量,这个值也是整个uboot从flash移到内存的偏移量。等同于(Destination Address - CFG_MONITOR_BASE)
1:lw t3, 0(t0)sw t3, 0(t1)addu t0, 4ble t0, t2, 1baddu t1, 4按字拷贝,把uboot bin的内容从源地址(flash)拷贝到目的地址(内存),拷贝的长度是从uboot开始到uboot_end_data为止,uboot_end_data后面是bss段,详见uboot.ldsaddi t0, a2, in_ram - _startj t0nop计算in_ram在内存中的新地址保存到t0,然后跳转到内存中运行in_ram。从此开始,uboot的代码将在ram中运行了.gpword_GLOBAL_OFFSET_TABLE.word uboot_end_data.word uboot_end.word num_got_entries
in_ram:t3 = num_got_entries,t4 = 新的GOT[2]li t2, 2
1:lw t1, 0(t4)beqz t1, 2fadd t1, t6sw t1, 0(t4)
2:addi t2, 1blt t2, t3, 1baddi t4, 4这里是一个循环,从GOT[2]开始,判断如果GOT表项有内容,则把内容从旧的GOT表拷贝到新的GOT表里。为什么要做拷贝呢?上面的程序已经把uboot整个程序从flash拷贝到了ram里,注意,只是内容拷贝,GOT里的地址还是老地址,所以要做重定位(如果是静态编译且属于模块内相对偏移,就不需要这个步骤了)。手工重定位的方法就是把旧GOT里的内容读取,然后加上偏移(uboot在flash与ram的偏移)赋值给新GOT里的对应表项程序构建过程(编译和生成程序时的链接)为每个链接单元(构成动态链接程序的二进制文件,如.o、.a、.so)至少定义一个GOT,每个函数都可以找到自己的GOT,因为GOT的位置离链接单元的入口点的偏移量是固定已知的。链接单元作为一个整体载入内存,所以GOT的内部偏移量与编译时是一样的。u-boot在编译时使用-fpic,会生成一个.got段来存储绝对地址符号。lw t1, -12(t0)lw t2, -8(t0)add t1, t6add t2, t6sub t1, 4
1:addi t1, 4bltl t1, t2, 1bsw zero, 0(t1)t1 = uboot_end_data,      t2 = uboot_end进行BSS段的清零,此时还没有操作系统,动态链接器,加载器等这些东东都还没有,所以要手动执行清零move a0, a1la t9, board_init_rj t9move a1, a2跳转到ram中的board_init_r执行,根据MIPS ABI规范,a0、a1分别是board_init_r的第一个、第二个参数,即board_init_r (gd_t *id, ulong dest_addr)中id = a0,dest_addr = a2

MIPS架构之start.s汇编分析相关推荐

  1. 基于ar9331 mips架构AP121 uboot分析(3) 启动流程

    mips架构u-boot启动流程 u-boot的启动过程大致做如下工作: 1.cpu初始化 2.时钟.串口.内存(ddr ram)初始化 3.内存划分.分配栈.数据.配置参数.以及u-boot代码在内 ...

  2. mips架构汇编指令

    mips架构特点 MIPS32 架构中是没有 EBP 寄存器的,程序函数调用的时候是将当前栈指针向下移动 n 比特到该函数的 stack frame 存储组空间,函数返回的时候再加上偏移量恢复栈 传参 ...

  3. 【优化系列】MIPS架构汇编优化资料

    DATE: 2021.8.3 文章目录 前言 1.MIPS介绍 2.MIPS汇编入门基础 3.MIPS汇编优化手册 3.1.中文手册 3.2.英文手册 3.3.Loongson 3A 优化 前言 在学 ...

  4. 【汇编优化】之MIPS架构优化

    序 本文属于回忆性文章,主要目的可归为资料整理. 1. MIPS 架构寄存器介绍 1.1 MIPS架构32位处理器的寄存器介绍 http://logos.cs.uic.edu/366/notes/mi ...

  5. MIPS架构——汇编代码转机器代码编译器 Matlab GUI

    MIPS架构下的MCU,指令集包含R-Type.I-Type.J-Type三种,在数电课程设计时为了给MCU编写指令集,需要将汇编语言转化成机器代码,这里分享一下自己写的Matlab 的 GUI. 主 ...

  6. MIPS架构下LW指令的重定位过程

    通常我们不会去关心指令重定位(relocation)的细节,编译器的ld过程已经帮助我们做好了.由于最近在移植CRIU,涉及到指令的重定位计算,不得不细细研究代码重定位的细节知识.之前的文章介绍了MI ...

  7. linux arm current_thread_info定义,linux中arm/mips架构current_thread_info定义

    arm架构 current 宏的定义: linux-3.4\arch\arm\include\asm\current.h 中: static inline struct task_struct *ge ...

  8. 汇编分析golang循环

    女主宣言 今天小编为大家分享一篇关于Golang循环汇编分析的文章,文章中介绍了golang循环的汇编层面的处理,通过分析,我们可以更了解循环的实现.希望能对大家有所帮助. PS:丰富的一线技术.多元 ...

  9. 计算机组成原理mips描述,计算机组成原理与接口技术:基于MIPS架构/华中科技大学教学改革建设教材...

    <计算机组成原理与接口技术:基于MIPS架构/华中科技大学教学改革建设教材>以MIPS微处理器为背景,全面阐述了计算机组成原理与接口技术.首先简要阐述了计算机系统的基本构成.结构模型.工作 ...

最新文章

  1. 【OpenCV 4开发详解】分割图像——Grabcut图像分割
  2. IEDA中彻底删除项目
  3. 全局处理ajax请求时session超时
  4. 工业4.0时代企业如何用CRM实现模式变革
  5. Android应用中Back键的监听及处理
  6. mysql5.6主从复制(读写分离)方案_MySQL5.6主从复制(读写分离)方案
  7. python解析sql语句表名_python正则表达式匹配sql语句中的表名
  8. VMware ESXI 5.0群集+ISCSI存储
  9. java 静态初始化数据_Java 静态数据初始化的示例代码
  10. 一、node.js的windows环境设置
  11. 使用NewtonSoft.JSON.dll来序列化和发序列化对象
  12. paip.备份导出ANDROID安卓自带记事本内容
  13. WebRTC中码率限制参数使用及sdp中参数使用流程
  14. 电脑打印机print spooler服务总是自动停止的解决方法...
  15. Mac —— QuickTime录屏 声音小解决
  16. BZOJ 3097 Hash Killer I
  17. mocha-only和skip的用法
  18. 【Jsoup】 基本使用
  19. 英文版系统远程桌面无法连接到远程计算机,windows server 2016远程桌面进去,英文系统修改语言...
  20. c语言清华大学出版社答案,《C语言程序设计》(清华大学出版社)书后习题参考答案...

热门文章

  1. 【Computer Organization笔记03】信息编码与码制转换,数据表示:检错与纠错、码距、汉明码等
  2. java线程池需要shutdown吗_公用线程池要不要shutdown?
  3. html中怎么给url格式化,如何将文本中的url提取出来格式化,然后将其它的html escape?...
  4. Java大对象lob_JavaEE JDBC 读写LOB大对象
  5. document.addEventListener理解
  6. mysql 多个表union查询_mysql查询两个表,UNION和where子句
  7. VoltDB培训PPT一则
  8. JSON值的类型:数字,字符串,逻辑值,数组,对象,null
  9. oracle中lag()函数和lead()函数的用法(图文)
  10. 用户是如何浏览你的网站的