~杂记(2):StartUP.s文件

1. S文件中的汇编知识

汇编程序中以 . 开头的名称 并不是指令的助记符,不会被翻译成机器指令。
而是给汇编器一些特殊指示,称为汇编指示(Assembler Directive)或伪操作(Pseudo-operation),由于它不是真正的指令所以加个“伪”字。

.section 划分段

.section指示把代码划分成若干个段(Section),程序被操作系统加载执行时,每个段被加载到不同的地址,操作系统对不同的页面设置不同的读、写、执行权限。
例如:

.section .data 	//.data段保存程序的数据,是可读可写的,相当于C程序的全局变量。(data segment)
.section .text	//.text段保存代码,是只读和可执行的,后面那些指令都属于.text段。(code segment/text segment)
.section .bss	//.bss段用来存放程序中未初始化的全局变量的一块内存区域,BSS是英文Block Started by Symbol的简称。BSS段属于静态内存分配。 
.section .vectors	//中断向量段。
//补充--------------------------------------------------------------------------------
//堆(heap)	当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减) 

//栈(stack) 	存放程序临时创建的局部变量,也就是说我们函数括弧“{}”中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变量)。

.globl 声明变量到链接器

.globl 用于声明变量,并通知编译器,在目标文件的符号表中标记它是一个全局符号。表明该变量会被链接器用到。例如:

/*
_start是一个符号(Symbol)
_start就像C程序的main函数一样特殊,是整个程序的入口
每个汇编程序都要提供一个_start符号并且用.globl声明
一个符号没有用.globl声明,就表示这个符号不会被链接器用到
*/
.globl _start

_start:	//这里定义了_start符号,它后面一条指令的地址作为这个符号所代表的地址
(略)

.align 对齐段落

.align 后面接立即数,缺省是4字节对齐。属于编译器的指令(不属于ARM指令)。

 .section .vectors
 .align  10

.import 导入外部标号

.import 声明标号来自外部文件,跟C语言中的EXTERN关键字类似

.import irq_dispatch
.import g_int_cnt

.space 分配内存空间

.space  0x200

.word或.long 数据定义

为特定的数据分配存储单元,也可以完成已分配储存单元的初始化

.long Reset_Handler
.long vec_handler
(略)
/*
ADS和GNU两种环境下的对比
.byte == DCB(分配字节存储单元)-128~255之间的数字或字符串
.hword或.short == DCW(分配半字存储单元)-32768~65535间的数字表达式
.word或.long == DCD(分配字存储单元)是表达式
.quad == 8字节
.float ==定义浮点数
.string/.asciz/.ascii ==定义多个字符串
*/

2、操作指令

相关知识

  1. 指令和伪指令。
  2. 大写风格的指令和小写风格的指令。

CPU和内存的数据交换

  1. ldr(load register)指令将内存内容加载入通用寄存器。
  2. str(store register)指令将寄存器内容存入内存空间中。
  3. ldr/str组合用来实现 ARM CPU和内存数据交换。

8种寻址方式

  1. 寄存器寻址 mov r1, r2。
  2. 立即(立即数)寻址 mov r0, #0xFF00。
  3. 寄存器移位寻址 mov r0, r1, lsl #3。
  4. 寄存器间接寻址 ldr r1, [r2] 表示内存,内存地址存在r2这个寄存器中,把内存地址里的值给r1。
  5. 基址变址寻址 ldr r1, [r2, #4]内存地址在r2+4里面。
  6. 多寄存器寻址 ldmia r1!, {r2-r7, r12}一次访问多个寄存器。
  7. 堆栈寻址 stmfd sp!, {r2-r7, lr}。
  8. 相对寻址 beq flag。

指令后缀

B(byte)功能不变,操作长度变为8位
H(half word)功能不变,长度变为16位
S(signed)功能不变,操作数变为有符号
如 ldr ldrb ldrh ldrsb ldrsh
S(S标志)功能不变,影响CPSR标志位
如 mov和movs movs r0, #0

实例解读(很多指令不知道什么意思,只知道就是在配置设备)

希望看的懂得朋友,告诉我一下,我再修改。

Reset_Handler:     /* set the priority cpu ahb */     
    lrw       r0, AHB_BASE     //把AHB基地址加载到R0中。lrw可以理解为loader Word
    movi    r1, 0x1     		 //向R1移动立即数。move immediate number
    movi    r2, 0x2     
    movi    r3, 0x3     
    movi    r4, 0x4     
    stw     r1, (r0, 0x0)     	//将R1中的内容存放到AHB的偏移地址0x0所在内存空间。store word
    stw     r2, (r0, 0xc)     
    stw     r3, (r0, 0x4)     
    stw     r4, (r0, 0x8) 
    /* restore the eflash state when system reboot from deep sleep */
    lrw     r0, PMU_LP_CONTROL
    ldw     r1, (r0, 0)
    btsti   r1, 5
    bf      .LSetClk
    lrw     r0, EFLASH_CONTROL_BASE
    movi    r1, 0x35
    stw     r1, (r0, 0x24)
    movi    r1, 0x16
    stw     r1, (r0, 0x28)
    movi    r1, 0x35
    stw     r1, (r0, 0x2c)
    movi    r1, 0x1b9
    stw     r1, (r0, 0x30)
    movi    r1, 0x8b10
    stw     r1, (r0, 0x34)

3、参考文章

https://www.cnblogs.com/snail-micheal/p/4189632.html
https://www.cnblogs.com/zhangj95/p/5646334.html
https://wenku.baidu.com/view/bad36fb577232f60dccca19a.html
https://blog.csdn.net/wuyuzun/article/details/70518507
https://www.cnblogs.com/wxb20/p/6249580.html

猜你喜欢

转载自blog.csdn.net/Kshine2017/article/details/84308045
今日推荐