习惯了使用C语言的情况下我发现自己对与汇编程序的符号和变量的理解很不深刻,今天抽空来学学加深理解。以ARM汇编来说,在汇编代码中所有以"."开头的指令都是汇编伪指令,他们不属于ARM指令集。常常在汇编代码中看到如下的使用方式但很少深入理解这样的写法的深层实现意义。究竟这两种使用方式区别是什么呢?

.global    xxxx
.word xxxx

查阅GNU的汇编伪指令说明后按我理解的我将两者按如下的方式解释:

.global

修饰标号为全局的,用法 .global xxx 这个符号可以被当前源文件以外的其他文件使用也可以被连接脚本(连接器)使用,xxx仅仅是一个标号对应一个地址并不是C中的一个变量。
无法对他取地址,因为他本身代表一个地址,仅仅是一个对应到一个编译过程中的值的别名,类似C代码中的define 定义的一样,只是在链接时他的值是由连接器自动处理的。
汇编代码使用仅能使用ldr,Rx,=xxx;而不能使用ldr,Rx,xxx

.word

汇编一个字的内存块,用法 .word expressions 这个expressions 可以是一个数也可以是一个符号或表达式。 如果是一个数则这里直接放置的就是这个值。如果是一个标号则
这个标号最后值就会存放这里,标号的值就是这块内存的地址。可以在C语言中直接使用extern uint32_t expressions来读写这个变量。
汇编中的使用同.global。expressions还可以是连接脚本中定义的符号。

这里 和word相同的功能的伪指令还有

.byte 			;定义单字节数据
.hword/.short ;定义双字节数据
.word/.long /.int ;定义4字节数据
.quad ;定义8字节数据
.float/.single ;定义32bit 浮点数
.double ;定义64bit浮点数
.ascii ;定义字符串以/0为结束符
例: .ascii "hello\0"
.asciz /.string ;定义字符串(非零结束符)
例: .string "hello"
.fill ;分配一段字节内存单元,用size长度value填充repeat次
例: .fill 10,2,6 ;将两个字节长度的6重复填充10次
.zero ;分配一段字节内存单元,并用0填充内存
例: .zero 10 ;分配十个字节单元,并用0填充
.space/.skip ;分配一段内存单元,用value将内存单元初始化
例: .space 10,6 ;分配十个字节单元,并用6填充

实例代码(来自liteos):

    /* 修饰标号 __LOS_HEAP_ADDR_START__  下同 */
.global __LOS_HEAP_ADDR_START__
.global __LOS_HEAP_ADDR_END__
/* 定义标号 __LOS_HEAP_ADDR_START__ 下同 */
__LOS_HEAP_ADDR_START__:
.word __los_heap_addr_start__
__LOS_HEAP_ADDR_END__:
.word __los_heap_addr_end__

符号(或标号)

仅存在程序构建过程而不存在于最终目标文件中,常常配合编译和链接脚本使用,其保存的是地址信息。

变量

最终会在运行RAM中找到,如果是全局的就会一直存在。符号或标号指向一个地址,如下就是定义变量(连接器会预留这块内存),__los_heap_addr_start__指向一块内存,他的意思更像C语言中的变量实际对应特定地址的内存。

顺带查到的伪指令记一下:

.syntax

ARM架构下使用的定义汇编语法格式伪指令,用法 .syntax [unified | divided],其中divided为缺省值。 divided 此时使用旧的汇编风格,此时ARM和THUMB指令有着各自的语法。 使用unified时,ARM和THUMB指令使用统一的语法,有着以下的主要特性:

立即数不需要#前缀 可能会出现IT指令,如果出现,则根据后面的条件码进行验证。

在ARM模式下,它不会生成机器码,而在THUMB模式下则会生成机器码

对于ARM指令,条件码总是出现在指令的最后;对于THUMB指令,条件码可以被使用,但仅限于IT指令的范围内 V6T2架构(及更高版本)的所有新指令都可用(这些指令中,divided语法仅支持少部分) 支持.N和.W后缀

.thumb 指定使用thumb指令集

.cpu 指定cpu类型如cortex-m0

.fpu 指点浮点计算指令的类型,有soft,softfp,hard 具体参考编译器的帮助文档一般在编译器路径的/share下有编译器的帮助文档。

.arch 指定代码目标架构,如armv7-a

.type 指定符号类型

参考源码地址:https://gitee.com/LiteOS/LiteOS/blob/master/targets/Cloud_STM32F429IGTx_FIRE/los_startup_gcc.S

参考博客:https://blog.csdn.net/gameit/article/details/13169307

ARM汇编--汇编中符号和变量的更多相关文章

  1. ARM嵌入式开发中的GCC内联汇编__asm__

    在针对ARM体系结构的编程中,一般很难直接使用C语言产生操作协处理器的相关代码,因此使用汇编语言来实现就成为了唯一的选择.但如果完全通过汇编代码实现,又会过于复杂.难以调试.因此,C语言内嵌汇编的方式 ...

  2. 从汇编看c++中指向成员变量的指针(二)

    在从汇编看c++中指向成员变量的指针(一)中讨论的情形没有虚拟继承,下面来看看,当加入了虚拟继承的时候,指向成员变量的指针有什么变化. 下面是c++源码: #include <iostream& ...

  3. 在汇编代码中调用C函数

    对于ARM体系来说,不同语言撰写的函数之间相互调用(mix calls)遵循的是 ATPCS(ARM-Thumb Procedure Call Standard),ATPCS主要是定义了函数呼叫时参数 ...

  4. ARM标准汇编与GNU汇编

    ARM标准汇编与GNU汇编 http://www.cnblogs.com/hnrainll/archive/2011/05/17/2048315.html

  5. ARM常用汇编指令介绍

    b     跳转指令(跳转范围为32Mb) bl    带返回地址的跳转,指令自动将下一条指令的地址复制到R14寄存器,然后跳转到指定地址去执行,执行完后返回到下一条指令处执行 pc    寄存器R1 ...

  6. vs中调试程序查看变量在内存中的内容的方法

    vs中调试程序 查看变量在内存中的内容的方法 https://blog.csdn.net/guojg1988/article/details/42922149 原文链接:http://www.sows ...

  7. [.net 面向对象编程基础] (5) 基础中的基础——变量和常量

    [.net面向对象编程基础]  (5) 基础中的基础——变量和常量 1.常量:在编译时其值能够确定,并且程序运行过程中值不发生变化的量. 通俗来说,就是定义一个不能改变值的量.既然不能变动值,那就必须 ...

  8. javascript 中$符号是代表什么意思!

    $符号在php中是表示变量的特征字符, 在js中它也有很多作用, 一般我们用来命名一个函数名称,获取id的 1. 首先可以用来表示变量, 比如变量 var s='asdsd'或var $s='asda ...

  9. jQuery中 $ 符号的冲突问题

    jQuery中 $ 符号的冲突问题是常见问题之一.   在jQuery中,$是jQuery的别名,为了书写方便,我们更习惯用$('#id')这一类的方式来书写代码.当同一页面引用了jQuery多个版本 ...

随机推荐

  1. Cisco IOS

    IOS Internetwork Operating System 互联网操作系统(基于UNIX系统) Cisco IOS 软件提供多种网络服务进而支持各种网络应用. Cisco IOS用户界面的基本 ...

  2. 【UltraISO】中文破解版

    下载链接:https://cn.ultraiso.net/uiso9_cn.exe简体中文版专用:   注册名:Guanjiu    注册码:A06C-83A7-701D-6CFC多国语言版专用:   ...

  3. Jmeter如何录制APP客户端脚本

    简单五步教大家Jmeter录制APP客户端脚本: Step1 右键单击该测试计划,选择"添加"-"线程组",添加一个线程组. Step2 为了录制客户端的操作, ...

  4. __new__() to create it, and __init__() to customize it 类方法 实例方法

    https://docs.python.org/3/reference/datamodel.html#object.__init__

  5. bcprov-jdk15on包用于创建CSR(证书请求)

    <!-- Eureka注册中心客户端依赖 --> <dependency> <groupId>org.springframework.cloud</group ...

  6. C#Process调用外部程序

    前言 使用C#调用外部程序,一种是通过Process类,一种是通过命令行,本文主要说一下使用C#中的Process类调用外部程序的方式. 过程: 1. 创建Process对象 2. 配置启动选项(输入 ...

  7. fedora 20安装vim Transaction check error

    Transaction check error安装时 yum remove vim-minimal 再安装vim ok

  8. Docker --volume(数据持久化)

    数据卷 volume 数据卷 是一个可供一个或多个容器使用的特殊目录,实现让容器中的一个目录和宿主机中的一个文件或者目录进行绑定.数据卷 是被设计用来持久化数据的 第一种:bind mount vol ...

  9. C++ 标准模板库(STL):vector

    目录 1. vector 1.1 vector的定义 1.2 vector容器内元素的访问 1.3 vector 常用函数实例解析 1.4 vector的常见用途 1. vector 变长数组,长度根 ...

  10. 一个ftp协议传输文件之后执行脚本无法工作的情况

    作者:良知犹存 转载授权以及围观:欢迎添加微信号:Conscience_Remains 总述         移植一个文件系统时候,我在window下git clone了对方仓库源码,然后用FileZ ...