【微机原理实战笔记】浅入理解汇编源文件

记录在学习微机原理时候的知识点,以便温故而知新。
Rd:目的操作数的寄存器
Rn、Rm:代指源操作数的寄存器
#num:代指立即数
label:代指标号

汇编源文件代码结构

文件类型

汇编语言中的文件类型通常与所使用的汇编器和目标平台有关。但一般来说,可以识别以下几种常见的文件类型:

源文件(.asm 或 .s):
这是包含汇编指令的文本文件,在嵌入式开发中用到的启动文件也是属于源文件一类,例如:startup_gd32f30x_hd.s。汇编程序员直接编辑这个文件,并使用汇编器将其转换为机器代码或目标代码。
列表文件(.lst):
当汇编器处理源文件时,它可能会生成一个列表文件,其中包含源代码的副本以及与之相关的注释和信息。这通常用于调试和文档目的。
目标文件(.obj 或 .o):
这是汇编器从源文件生成的二进制文件。它包含机器代码,但可能还包含一些元数据,如符号表,这些元数据在链接阶段会被用到。
可执行文件(.exe, .com, .bin 等):
这是链接器从目标文件和其他必要的库生成的最终文件。它是一个可以直接在特定平台上运行的二进制文件。
库文件(.lib 或 .a):
库文件包含一组预编译的代码(通常是函数或例程),这些代码可以在多个程序中重用。汇编器或链接器可以使用库文件来减少最终生成的可执行文件的大小。
.map文件(.map):
链接器可能会生成一个地图文件,它描述了可执行文件中的内存布局,包括各个段(如代码段、数据段等)的位置和大小,以及符号的地址。
错误和警告文件:
在编译和链接过程中,可能会生成包含错误和警告信息的文件。这些文件帮助程序员识别和修复源代码中的问题。

堆栈对齐与指示编译器

在汇编语言中,不同的堆栈对齐通常是通过使用特定的伪指令或编译器选项来控制的。我的代码使用的是通过伪指令来设置堆栈对齐。具体的写法会依赖于你使用的汇编器和目标平台。以下是一些常见的方法来控制堆栈对齐:

使用伪指令:
某些汇编器提供了伪指令来设置堆栈对齐。像 PRESERVE8 这样的伪指令,它告诉汇编器保持堆栈八字节对齐。不同的汇编器可能提供不同的伪指令来实现不同的对齐要求。
编译器选项:
如果你在使用高级语言(如C或C++)并通过编译器生成汇编代码,你可以通过编译器选项来控制堆栈对齐。例如,在GCC中,你可以使用 -mstackrealign 选项来启用堆栈重新对齐。
直接设置堆栈指针:
在汇编代码中,你可以直接操作堆栈指针(如 SP 或 RSP,取决于架构)来实现特定的对齐。这通常涉及到计算对齐所需的额外空间,并相应地调整堆栈指针。这种方法比较底层且复杂,需要深入理解目标平台的堆栈机制。
使用内存对齐属性:
对于局部变量或全局变量,你可以使用特定的属性或修饰符来指定其对齐方式。这不会直接影响堆栈指针本身,但会确保变量在内存中以特定方式对齐。
链接器脚本:
在某些情况下,你可以通过编写链接器脚本来控制堆栈的对齐。链接器脚本定义了如何组织和布局程序的内存段,包括堆栈段。

PRESERVE8  ;8字节对齐
THUMB      ;使用THUMB指令集

PRESERVE8 是一个汇编伪指令,用于指定当前文件保持堆栈8字节对齐,并设置相应的编译属性以通知链接器。在特定的汇编环境或工具中,PRESERVE8伪指令可能具有特定的语法和用法,用于控制堆栈对齐的属性。这种对齐要求对于某些硬件架构和编译器来说可能是必要的,以确保程序的正确运行和性能优化。
THUMB THUMB在代码中用于指示编译器,指的是该文件使用Thumb指令集。

输出、输入

EXPORT
IMPORT

在汇编语言编程中,EXPORT 和 IMPORT 通常与链接器(linker)和符号(symbol)管理相关。这两个指令用于声明函数或变量的可见性,以便在多个源文件或模块之间共享它们。

EXPORT

EXPORT 通常用于声明一个函数或变量,使其可以从当前模块(例如一个对象文件或库)被其他模块引用。换句话说,EXPORT 使一个符号在链接过程中对其他模块可见。

例如,在 ARM 的汇编语言中,你可能会看到这样的代码:

;这告诉链接器 Reset_Handler 是一个可以从其他模块引用的函数。
EXPORT Reset_Handler
			  
Reset_Handler	PROC
	  ; 函数体
	  ENDP	

IMPORT

IMPORT 用于声明一个函数或变量,表明在当前模块中将会使用到在其他模块中定义的这个符号。这告诉链接器在链接过程中需要查找并解析这个符号。

例如,在 ARM 的汇编语言中,你可能会看到这样的代码:

; Data_Function 是在另一个模块中定义的函数,当前模块通过 IMPORT 声明它,并在代码中调用它。
IMPORT Data_Function  
  
start:  
    BL Data_Function   ; 调用在另一个模块中定义的函数

弱引用

弱引用通常意味着对某个实体(如函数或变量)的引用,它允许其他更强的引用(即非弱引用)覆盖或替换它。当同时存在其他同名标号时,优先使用其他标号。

EXPORT Reset_Handler        	[WEAK]	 

宏定义

在汇编语言中,宏定义(macro definition)通常用于简化重复的代码片段或创建可重用的代码块。宏允许你定义一段代码,然后在多个地方以相同或不同的参数调用它。不同的汇编器和汇编语言可能有不同的宏定义语法和特性。以下是一些常见的汇编语言中宏定义的基本写法和概念:

通用概念
参数: 宏可以接受一个或多个参数,这些参数在宏定义时通过占位符或特定语法来指定,并在宏调用时替换为实际的值或变量。
局部标签: 有些汇编器允许在宏定义中使用局部标签,这些标签在宏展开时会被重命名以防止冲突。
条件汇编: 一些宏定义可能包含条件语句,这些语句在宏展开时根据某些条件决定是否包含特定的代码片段。
嵌套宏: 一些汇编器支持宏的嵌套定义,即在一个宏内部定义另一个宏。

MASM (Microsoft Macro Assembler) 宏定义

在 MASM 中,你可以使用 .MACRO 和 .ENDM 指令来定义宏。例如:

;/*********************************************************************************************************
;*                                              宏定义
;*********************************************************************************************************/
.MACRO MyMacro param1, param2  
    MOV param1, param2  
.ENDM

然后你可以在代码中使用 MyMacro 并传递参数:

MyMacro var1, var2			;这将会展开为:MOV var1, var2

NASM (Netwide Assembler) 宏定义

在 NASM 中,你可以使用 %macro 和 %endmacro 来定义宏,并使用 %1, %2, 等来引用参数。例如:

;/*********************************************************************************************************
;*                                              宏定义
;*********************************************************************************************************/
%macro MyMacro 2  
    mov %1, %2  
%endmacro

然后你可以这样使用它:

MyMacro var1, var2			;这将会展开为:MOV var1, var2

在Keil中,我们一般通过MACRO定义宏。

MACRO _LED_ 

常量段、变量段与代码段

“常量段”区、“变量段”区和“代码段”区通过 AREA 进行分段,并根据各段的特点设置相应的属性。“常量段”区用于定义常量“变量段”区用于定义变量,“代码段”区用于定义函数。MainConstData、MainStaticData和.text是段的名称,无特殊作用,段名若以非字母开头则必须包含在符号“|”中DATA、CODE、READONLY和READWRITE为段的属性,DATA和CODE用于指示编译器,该段用于存储数据或代码,READONLY和READWRITE用于设置该段的读/写属性为“只读”或“可读可写”。

;/*********************************************************************************************************
;*                                              常量段
;*********************************************************************************************************/
  AREA  MainConstData,  DATA,  READONLY
;/*********************************************************************************************************
;*                                              变量段
;*********************************************************************************************************/
  AREA  MainStaticData,  DATA,  READWRITE
;/*********************************************************************************************************
;*                                              代码段
;*********************************************************************************************************/
  AREA |.text|, CODE, READONLY

文件结束

ALLGN 4				;检查当前位置,文件结束位置是否按4字节对齐。若未对其则填充 NOP空指令使其对齐,便于CPU快速访问。
END					;END用于指示编译器该文件已结束。

小记

THUMB
它是ARM指令集的一个子集,针对代码密度问题而提出,具有16位的代码宽度。Thumb指令集在保留32位代码优势的同时,大大节省了系统的存储空间。Thumb指令集并不是完整的体系结构,它并不能独立执行,而是与ARM指令集共同存在,处理器可以在ARM工作状态和Thumb工作状态之间切换。Thumb指令集分为Thumb-1指令集和Thumb-2指令集,其中Thumb-1指令集是16位指令集,而Thumb-2指令集在Thumb-1的基础上增加了一些32位指令,其性能与ARM指令集类似。

特殊寄存器

  • 23
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值