精华内容
下载资源
问答
  • GNU ARM汇编

    2014-03-18 20:22:47
    Linux下ARM汇编语法尽管在Linux下使用C或C++编写程序很方便,但汇编源程序用于系统最基本的初始化,如初始化堆栈指针、设置页表、操作 ARM的协处理器等。初始化完成后就可以跳转到C代码执行
  • GNU ARM 汇编入门.pdf

    2021-05-15 21:28:08
    GNU ARM 汇编入门GNUARMGNUARMGGNNUUAARRMM 汇编入门第一部分 Linux 下ARM 汇编语法第一部分 Linux 下ARM 汇编语法第第一一部部分分 LLiinnuuxx下下AARRMM汇汇编编语语法法尽管在Linux 下使用C 或C++编写程序很方便...

    GNU ARM 汇编入门

    GNUARM

    GNUARM

    GGNNUUAARRMM 汇编入门

    第一部分 Linux 下ARM 汇编语法

    第一部分 Linux 下ARM 汇编语法

    第第一一部部分分 LLiinnuuxx下下AARRMM汇汇编编语语法法

    尽管在Linux 下使用C 或C++编写程序很方便,但汇编源程序用于系统最基本的初始

    化,如初始化堆栈指针、设置页表、操作 ARM 的协处理器等。初始化完成后就可以跳转到

    C 代码执行。需要注意的是,GNU 的汇编器遵循AT&T 的汇编语法,可以从GNU 的站点

    ()上下载有关规范。

    .Linux

    .Linux

    一..LLiinnuuxx汇编行结构

    任何汇编行都是如下结构:

    [:] [} @ comment

    [:] [} @ 注释

    LinuxARM 汇编中,任何以冒号结尾的标识符都被认为是一个标号,而不一定非要在

    一行的开始。

    【例1】定义一个"add"的函数,返回两个参数的和。

    .section .text, “x”

    .global add @ give the symbol add external linkage

    add:

    ADD r0, r0, r1 @ add input arguments

    MOV pc, lr @ return from subroutine

    @ end of program

    .Linux

    .Linux

    二..LLiinnuuxx 汇编程序中的标号

    标号只能由a~z,A~Z,0~9,“.”,_等字符组成。当标号为0~9的数字时为局部标

    号,局部标号可以重复出现,使用方法如下:

    标号f: 在引用的地方向前的标号

    标号b: 在引用的地方向后的标号

    【例2】使用局部符号的例子,一段循环程序

    1:

    subs r0,r0,#1 @每次循环使r0=r0-1

    bne 1f @跳转到1 标号去执行

    局部标号代表它所在的地址,因此也可以当作变量或者函数来使用。

    .Linux

    .Linux

    三..LLiinnuuxx汇编程序中的分段

    (1).section伪操作

    用户可以通过.section伪操作来自定义一个段,格式如下:

    .sectionsection_name[,"flags"[,%type[,flag_specific_arguments]]]

    每一个段以段名为开始, 以下一个段名或者文件结尾为结束。这些段都有缺省的标志

    (flags),连接器可以识别这些标志。(与armasm中的AREA 相同)。

    下面是ELF 格式允许的段标志

    含义

    a 允许段

    w 可写段

    x 执行段

    【例3】定义段

    .section .mysection @自定义数据段,段名为 “.mysection”

    .align 2

    strtemp:

    .ascii "Temp string \n\0"

    (2)汇编系统预定义的段名

    .text @代码段

    .data @初始化数据段

    .bss @未初始化数据段

    .sdata @

    .sbss @

    需要注意的是,源程序中.bss段应该在.text 之前。

    四.. 定义入口点..

    汇编程序的缺省入口是 start 标号,用户也可以在连接脚本文件中用ENTRY标志指明

    其它入口点。

    【例4】定义入口点

    .section.data

    < initialized data here>

    .section .bss

    < uninitialized data here>

    .section .text

    .globl _start

    _start:

    .Linux

    .Linux

    五..LLiinnuuxx汇编程序中的宏定义

    格式如下:

    .macro 宏名 参数名列表 @伪指令.macro定义一个宏

    宏体

    .endm@.endm表示宏结束

    如果宏使用参数,那么在宏体中使用该参数时添加前缀“\”。宏定义时的参数还可以使用

    默认值。

    可以使用.exitm伪指令来退出宏。

    【例5】宏定义

    .macro SHIFTLEFT a, b

    .if \b < 0

    MOV \a, \a, ASR #-\b

    .exitm

    .endif

    MOV \a, \a, LSL #\b

    .endm

    .Linux

    .Linux

    六..LLiinnuuxx汇编程序中的常数

    (1)十进制数以非0数字开头,如:123和9876;

    (2)二进制数以0b开头

    展开全文
  • GNU ARM Assembler Quick...GNU ARM 汇编简明参考手册 A summary of useful commands and expressions for the ARM architecture using the GNU assembler is presented briefly in the concluding portion of this...

    GNU ARM Assembler Quick Reference
    GNU ARM 汇编简明参考手册

    A summary of useful commands and expressions for the ARM architecture using the GNU assembler is
    presented briefly in the concluding portion of this Appendix.
    在本附录的最后部分简要介绍了使用GNU汇编程序的ARM体系结构的有用命令和表达式。

    Each assembly line has the following format:
    [<label>:] [<instruction or directive>} @ comment
    没一行汇编代码都遵循如下的格式:
    [<标号>:] [<指令或伪操作>} @ 注释

    Unlike the ARM assembler, using the GNU assembler does not require you to indent instructions and
    directives. Labels are recognized by the following colon instead of their position at the start of a line.
    与ARM汇编程序不同,使用GNU汇编程序不需要在指令或伪操作前缩进。标号由跟随在其后的“:”识别,而不是其在行首的位置。
     
    An example follows showing a simple assembly program defining a function ‘add’ that returns the sum of
    two input arguments:
        .section .text, “x”
        .global    add @ give the symbol add external linkage
        
        add:
            ADD    r0, r0, r1    @ add input arguments
            MOV    pc, lr        @ return from subroutine
                
                        @ end of program
    一个返回两个参数和的‘add’函数例子:
        .section .text, “x”
        .global    add @ 赋予add符号外部链接属性
        
        add:
            ADD    r0, r0, r1    @ r0 r1是传入的参数,可以搜索gnu eabi来获取更多信息
            MOV    pc, lr        @ lr存储了返回的指令地址,将lr赋值给pc就会从子程序返回
                
                        @ 程序结束

    GNU Assembler Directives for ARM
    ARM GNU 汇编伪操作

    The follow is an alphabetical listing of the more command GNU assembler directives.
    下表是按字母顺序排序的常见GNU 汇编伪操作

    GNU Assembler Directive                    Description
    GNU 汇编为操作                        描述
    .ascii “<string>”                     Inserts the string as data into the assembly (like DCB in armasm).
    .ascii "<字符串>"                    将字符串作为数据插入,可以通过添加一个标号引用它
                                hello:
                                    .ascii "hello"

    .asciz “<string>”                    Like .ascii, but follows the string with a zero byte.
    .asciz "<字符串>"                    和.ascii很像,但是会在字符串结尾附加'\0'

    .balign <power_of_2>                    Aligns the address to <power_of_2> bytes. The assembler
    {,<fill_value>                        aligns by adding bytes of value <fill_value> or a suitable default.
    {,<max_padding>} }                    The alignment will not occur if more than <max_padding> fill
                                bytes are required (similar to ALIGN in armasm).
    .balign <2的幂次>                    
    {,<填充字节>                        对齐地址到<2的幂次>的整倍数。汇编工具用<填充字节>或一个恰当的默认字节
    {,<最大填充字节数>} }                    从当前地址填充到对齐地址。需要填充的字节如果超过了<最大填充字节数>
                                对齐操作不会执行

    .byte <byte1> {,<byte2>} ...                Inserts a list of byte values as data into the assembly (like DCB in armasm).
    .byte <字节1> {,<字节2>} ...                将一列单字节范围的数值作为数据插入

    .code <number_of_bits>                    Sets the instruction width in bits. Use 16 for Thumb and 32 for
                                ARM assembly (similar to CODE16 and CODE32 in armasm).
    .code <bit位数>                        设定指令的宽度为<bit位数>位。Thumb为16,ARM为32。

    .else                            Use with .if and .endif (similar to ELSE in armasm).
    .else                            和 .if 和 .endif 一起使用

    .end                            Marks the end of the assembly file (usually omitted).
    .end                            标记汇编文件的结尾,一般会被省略
                                
    .endif                            Ends a conditional compilation code block – see .if, .ifdef, .ifndef (similar to ENDIF in armasm).
    .endif                            标记条件编译代码块的结束 - 参见 .if,.ifdef,.ifndef
        
    .endm                            Ends a macro definition – see .macro (similar to MEND in armasm).
    .endm                            标记宏定义的结束 - 参见 .macro

    .endr                            Ends a repeat loop – see .rept and .irp (similar to WEND in armasm).
    .endr                            结束一个重复循环 - 参见 .rept 和 .irp

    .equ <symbol name>, <value>                This directive sets the value of a symbol (similar to EQU in armasm)
    .equ <标记名>, <数值>                    这个伪指令设置<标记名>为<数值>,注意这里没有作为数据插入

    .err                            Causes assembly to halt with an error.
    .err                            停止汇编操作并报错

    .exitm                            Exit a macro partway through – see .macro (similar to MEXIT in armasm)
    .exitm                            在一个宏代码块的中间提前退出 - 参考 .macro

    .global <symbol>                    This directive gives the symbol external linkage (similar to EXPORT in armasm).
    .global <标记>                        这条伪操作使<标记>可以被外部链接

    .hword <short1> {,<short2>}                Inserts a list of 16-bit values as data into the assembly (similar to DCW in armasm).                
    ...
    .hword <short1> {,<short2>}                将一列两字节范围的数值作为数据插入
    ...

    .if <logical_expression>                Makes a block of code conditional. End the block using .endif
                                (similar to IF in armasm). See also .else.
    .if <逻辑表达式>                    根据<逻辑表达>真假决定是否执行紧随其后的代码块。使用.endif标记这个代码块的结束。
                                同时参考 .else.

    .ifdef <symbol>                        Include a block of code if <symbol> is defined. End the block with .endif.
    .ifdef <标记>                        如果<标记>被定义那么就包含紧随其后的代码块。使用.endif标记这个代码块的结束。

    .ifndef <symbol>                    Include a block of code if <symbol> is not defined. End the block with .endif.
    .ifndef <标记>                        如果<标记>没有被定义那么就包含紧随其后的代码块。使用.endif标记这个代码块的结束。

    .include “<filename>”                     Includes the indicated source file (similar to INCLUDE in armasm or #include in C).
    .include “<文件名>”                     包含<文件名>指定的源文件到当前文件中。

    .irp <param> {,<val_1>}                    Repeats a block of code, once for each value in the value list.
    {,<val_2>} ...                        Mark the end of the block using a .endr directive. In the
                                repeated code block, use \<param> to substitute the associated
                                value in the value list.    
    .irp <param> {,<val_1>}                    为每一个{,<val_n>}数值执行一次紧随其后的代码块,使用.endr标记这个代码段块的结束。
    {,<val_2>} ...                        在这个代码段中,可以通过\<param>来引用当前的{,<val_n>}的值。

    .macro <name> {<arg_1}                    Defines an assembler macro called <name> with N parameters.
    {,<arg_2>} ... {,<arg_N>}                The macro definition must end with .endm. To escape from the
                                macro at an earlier point, use .exitm. These directives are
                                similar to MACRO, MEND, and MEXIT in armasm. You must
                                precede the dummy macro parameters by \. For example:

                                .macro SHIFTLEFT a, b
                                    .if \b < 0
                                        MOV \a, \a, ASR #-\b
                                        .exitm
                                    .endif
                                    MOV \a, \a, LSL #\b
                                .endm
    .macro <name> {<arg_1}                    
    {,<arg_2>} ... {,<arg_N>}                看这个例子就行了
                                .macro SHIFTLEFT a, b
                                    .if \b < 0
                                        MOV \a, \a, ASR #-\b
                                        .exitm
                                    .endif
                                    MOV \a, \a, LSL #\b
                                .endm

    .rept <number_of_times>                 Repeats a block of code the given number of times. End with .endr.
    .rept <次数>                         重复执行一个代码块<次数>次,该代码块以.endr标记结束。

    <register_name> .req                     This directive names a register. It is similar to the RN directive
    <register_name>                        in armasm except that you must supply a name rather than a
                                number on the right (e.g., acc .req r0).
    <register_name> .req                     这个伪指令命名一个寄存器。(例如,acc .req r0)。
    <register_name>                        

    .section <section_name>                    Starts a new code or data section. Sections in GNU are called
    {,”<flags>”}                        .text, a code section, .data, an initialized data section, and
                                .bss, an uninitialized data section. These sections have default
                                flags, and the linker understands the default names (similar
                                directive to the armasm directive AREA). The following are
                                allowable .section flags for ELF format files:
                                <Flag>    Meaning
                                a    allowable section
                                w    writable section
                                x    executable section
    .section <段名>                        标记一个新的code或data段的开始。
    {,”<属性标志>”}                        GNU段名    描述
                                .text    a code section
                                .data    an initialized data section, and
                                .bss    an uninitialized data section.
                                这些段都有默认的属性标识,连接器可以识别处理这些默认的段名的属性
                                以下是允许的ELF格式文件的段属性标志
                                <标志>    含义
                                a    段需要占用内存
                                w    段可写
                                x    段可执行

    .set <variable_name>,                     This directive sets the value of a variable. It is similar to SETA in armasm.
    <variable_value>
    .set <变量名>,                         设置<变量名>为的值为<变量值>
    <变量值>

    .space <number_of_bytes>                Reserves the given number of bytes. The bytes are filled with
    {,<fill_byte>}                        zero or <fill_byte> if specified (similar to SPACE in armasm).
    .space <字节数>                        保留<字节数>个字节的空间,并用<填充字节>填充,如果没有指定<填充字节>则填充0。
    {,<填充字节>}

    .word <word1> {,<word2>} ...                Inserts a list of 32-bit word values as data into the assembly(similar to DCD in armasm).
    .word <word1> {,<word2>} ...                将一列32-bit范围的数值作为数据插入

    Assembler Special Characters / Syntax
    汇编器特殊字符及语法
        Inline comment char: ‘@’
        代码中的注释符号:'@'
        Line comment char: ‘#’
        整行注释符号:'#'
        Statement separator: ‘;’
        语句分割符:';'
        Immediate operand prefix: ‘#’ or ‘$’
        直接操作数前缀:'#' 或 '$'

    Register Names
    寄存器名
        General registers: %r0 - %r15     ($0 = const 0)
        通用寄存器: %r0 - %r15
        FP registers: %f0 - %f7
        FP寄存器: %f0 - %f7 (没有查到功能)
        Non-saved (temp) regs: %r0 - %r3, %r12
        临时寄存器(caller saved): %r0 - %r3,%r12
        Saved registers: %r4 - %r10
        全局寄存器(callee saved): %4 - %r10
        Stack ptr register: %sp
        堆栈指针寄存器: %sp
        Frame ptr register: %fp
        堆栈帧指针寄存器: %fp (和SP配合用于调试时backtrace功能)
        Link (retn) register: %lr
        链接返回寄存器: %lr (一是用来保存子程序返回地址;
                二是当异常发生时,LR中保存的值等于异常发生时PC的值减4(或者减2),
                因此在各种异常模式下可以根据LR的值返回到异常发生前的相应位置继续执行)
        Program counter: %ip
        程序计数器: %ip (应该是原文件错了,这里是%pc,ip应该指Intra-Procedure-call Scratch Register)
        Status register: $psw
        状态寄存器: $psw
        Status register flags: xPSR
        状态寄存器标识: xPSR
        (x = C current)    xPSR_all
        (x = S saved )    xPSR_f
                xPSR_x
                xPSR_ctl
                xPSR_fs
                xPSR_fx
                xPSR_fc
                xPSR_cs
                xPSR_cf
                xPSR_cx
                .. and so on

    Arm Procedure Call Standard (APCS) Conventions
    Arm过程调用标准(APCS)约定
    Argument registers: %a0 - %a4 (aliased to %r0 - %r4)
    参数寄存器: %a0 - %a4 (别名 %r0 - %r4)
    Returned value regs: %v1 - %v6 (aliased to %r4 - %r9)
    返回值寄存器:%v1 - %v6 (别名 %r4 - %r9)

    Addressing Modes
    寻址模式
    ‘rn’ in the following refers to any of the numbered registers, but not the control registers.
    'rn'代指除控制寄存器以外的寄存器
        addr Absolute addressing mode
        addr 绝对地址寻址模式,例如ldr r0,=msg
        %rn Register direct
        %rn 寄存器直接寻址,使用寄存器存储的值作为指令的参数
        [%rn] Register indirect or indexed
        [%rn] 寄存器间接寻址或下标寻址,寄存器存储的值是操作数的指针
        [%rn,#n] Register based with offset
        [%rn,#n] 寄存器基址偏移寻址,例如ldr r0,[%r1, #4]
        #imm Immediate data
        #imm 操作数在指令中直接使用

    Machine Dependent Directives
    机器相关伪操作
        .arm Assemble using arm mode
        .arm 汇编使用arm模式
        .thumb Assemble using thumb mode
        .thumb 汇编使用thumb模式
        .code16 Assemble using thumb mode
        .code16 汇编使用thumb模式
        .code32 Assemble using arm mode
        .code32 汇编使用arm模式
        .force_thumb Force thumb mode (even if not supported)
        .force_thumb 强制使用thumb模式,即使不支持
        .thumb_func Mark entry point as thumb coded (force bx entry)
        .thumb_func 标记函数的入口点为thumb代码(强制使用bx跳转)
        .ltorg Start a new literal pool
        .ltorg 标记一个新文字池的开始(文字池:嵌入式代码中用于存放常量的区域)

    Opcodes

    For detailed information on the machine instruction set, see this manual:
    更多关于机器指令集的详细信息请参考这些手册:
    ARM Architecture Reference Manual, Addison-Wesley ISBN 0-201-73719-1
    Here is a recommended book to get a lot of system developer information on the ARM architecture.
    ARM System Developer’s Guide, Morgan Kaufmann Publishers ISBN 1-55860-874-5 (alk.paper), authors:
    Andrew N. Sloss, Dominic Symes, Chris Wright, 2004

     

    展开全文
  • (十一)GNU ARM汇编语言

    2020-07-22 14:22:56
    文章目录一、ARMGNU编译器1)常用ARM开发环境2)ARM编译器二、编译器是一套工具三、ARM编译器与ARM GNU编译器区别(主要是汇编器)1)编译器设计的参考标准2)编译器设计实现3)编译器之间的伪操作差异四、ARM GNU...

    本专栏总结王利涛《C语言嵌入式Linux高级编程》第二期课程

    一、ARM与GNU编译器

    1)常用ARM开发环境

    • IAR
    • ADS1.2/SDT :ARM software Development kit
    • RVDS:Realview Developer Suite
    • Keil MDK
    • Real View MDK
    • GNU ARM交叉编译器

    2)ARM编译器

    • ARM编译器
    • GNU arm-linux-gcc bianyiqi

    二、编译器是一套工具

    arm编译器是一套工具,包含:

    • 编译器有:gcc、g++
    • 汇编器、链接器:as、ld
    • 二进制转换工具:objdump、objcopy-strip
    • 打包工具:ar
    • 调试工具:gdb
    • 库/头文件

    三、ARM编译器与ARM GNU编译器区别(主要是汇编器)

    1)编译器设计的参考标准

    这两个编译设计都是参考 ARM指令集。

    2)编译器设计实现

    • 标准指令:将高级程序翻译成ARM指令集规定的汇编指令。
    • 伪操作:将汇编指令组装成一个可运行的汇编程序。
      在这里插入图片描述
    • CPU内部的电路,决定了ARM的指令集。ARM编译器 和 ARM GNU编译器的设计参考了ARM指令集,并且各自的编译器都要属于自己的伪操作。编译器的作用是用来做翻译工作,将高级语言,转换成ARM指令集规定的汇编。

    3)编译器之间的伪操作差异

    ARM编译器ARM GNU编译器
    AREA copy, CODE,….text
    AREA dat, DATA,….data
    使用 ;注释使用/* */或@ 注释
    DCD.long / .word
    EntryEntry:
    END.end
    CODE32.arm/.code32
    SPACE.space
    GBLL/GBLA.global
    EXPORT.global
    IMPORT.extern
    EQU/SETL/SETA/equ/.set
    labellabel:
    :OR1
    :SHL:<<
    IF:DEF:ELSE ENDIF.ifdef .else .endif
    MACRO.macro
    MEND.endm
    GET test.h.include “test.h”

    四、ARM GNU编译常用伪操作

    伪操作说明
    ENTRY(_start)定义程序入口
    @注释
    .section .text/.data定义段
    .align地址对齐方式
    .quand / .long / .word整型数据定义
    .byte/ .short整形数据定义
    .string / .ascii / .asciz字符串定义
    .float浮点数定义
    .space 10 FF分配10个字节空间,填充为FF
    .equ / .set赋值语句
    .type func, @ function指定符号类型为函数
    .type num, @boject指定符号类型为对象[object->常数、变量]
    .include / .incbin展开头文件/二进制文件
    tmp .reg / .unreg r12给寄存器取别名
    .arm / .code32指定指令集格式
    .thumb / .code16指定指令集格式
    .poll / .ltory声明一个文字池
    .comm buf ,20在BSS段申请一段buf(未初始化)
    OUTPUT_ARCH(arm)指定可执行文件运行平台
    OUT_FOR MAT (“elf32-littlearm”)指定输出可执行文件格式
    ; / \n\t汇编语句分隔符
    # / $指定指令集版本
    .arch指定指令集版本
    .file汇编对应的C源文件
    .fpu浮点类型

    五、GNU汇编中的标号

    1)使用规则

    • 由字幕、数字、下划线和 . 等字符组成;
    • 局部标号由数字 N 组成,引用 :NF或Nb,表示往前或往后搜索;

    2)程序气短标号:_start

    • ARM GUN汇编默认使用 _start标号作为汇编程序的起点;
    • 如果希望该标号被其它文件引用,需要 .global _start 声明一下。

    六、section伪操作

    1)使用方法

    • 用户通过 .section伪操作定义一个段;
    • 格式:.section <section_name> {, "<flags>"}
    • .section , mysection(段名) “awx" @定义一个允许可写、可执行段
    • 每个段以段名开始,以下一个段名或文件结尾为结束
    • 系统预留的段名不可冲突:.text / .data / .bss /…

    七、GNU-ARM 汇编中的常数

    基本数据格式

    • 二进制以 0b/0B 开头,八进制以 0开头,十六进制以0x开头,十进制以非0常数开头;
    • 负数前加“-” ,取补用“~”, 不相等用“<>”, 其它符号: + - * % < << > >> | & ^;
    • 字符串常量用双引号 " " 括起来;
    • 当前地址可以用 . 表示, . 在汇编程序代表当前指令的地址;
    • 使用 .ascii "hello\0" 定义字符串要自行结尾加‘\0’,
      .string可以定义多个字符串:.string "hello", "world"
      ascize 可以定义一个以空字符结尾的字符串: .asciz "hello "
    • 使用 .rept 重复定义数据:.rept 3 .byte 0x10 .endr 连续定义3个.byte 0x10

    八、数据定义

    1)基本格式

    • 标签:命令

      f:
        .float 3.14
      
    • 符号赋值

      .eque f, 10
      

    2)定义静态符号

    • .equ除了赋值外,使用.equ 可以把常数定义为可以在代码段中使用的符号,类似于C语言中的#define 宏定义

      .section .data
      .equ DELAY, 100
      .section .text
       mov R0, $DELAY
      
    展开全文
  • GNU_ARM汇编入门.pdf

    2014-11-26 17:05:39
    GNU_ARM汇编入门
  •  ...目前常用的ARM汇编环境有以下两种:  A、ARM ASM:ARM公司的汇编器,适合在Windows平台下使用  B、GNU ARM ASM:GNU交叉编译工具链中的汇编器,适合于Linux开发平台。  GNU汇编器是GNU
    

    转载:http://9291927.blog.51cto.com/9281927/1786070

    同的汇编器对汇编语言的语法要求不一样。目前常用的ARM汇编环境有以下两种:

        A、ARM ASMARM公司的汇编器,适合在Windows平台下使用

        B、GNU ARM ASMGNU交叉编译工具链中的汇编器,适合于Linux开发平台。

        GNU汇编器是GNU工具集的一部分,用于将汇编语言文件转化为二进制obj文件。GNU汇编器针对的是多种处理器架构,这意味着GNU汇编器的语法不同于ARM工具链的汇编器。

    一、GUN ARM汇编指令格式

    1GNU ARM汇编指令格式

    GNUARM汇编指令的格式如下:

    [<label>:][<instruction or directive or pseudo-instruction>} @comment

    <label>: 为标号, GNU汇编中,任何以冒号结尾的标识符都被认为是一个标号,而不一定非要在一行的开始。

    Instruction指令

    Directive伪操作

    pseudo-instruction伪指令

    @comment:注释语句

    2、标号label的解析

    GNU ARM汇编指令中的标号只能由azAZ09“.”_等(由点、字母、数字、下划线等组成,除局部标号外,不能以数字开头)字符组成。

    标号label本质代表它所在行的地址,因此也可以当作变量或者函数来使用。段内标号的地址值在汇编时确定段外标号的地址值在连接时确定。

    标号label依据生成方式分为三类:

    A、基于PC的标号。基于PC的标号是位于目标指令前的标号或者程序中数据定义伪操作前的标号。这种标号在汇编时将被处理成PC值加上(或减去)一个数字常量,常用于表示跳转指令”b”等的目标地址,或者代码段中所嵌入的少量数据。

    B、基于寄存器的标号。基于寄存器的标号常用MAPFIELD来定义,也可以用EQU来定义。这种标号在汇编时将被处理成寄存器的值加上(或减去)一个数字常量,常用于访问数据段中的数据。

    C、绝对地址。绝对地址是一个32位数据。它可以寻址的范围为[0x000000000xFFFFFFFF]即可以直接寻址整个内存空间。

     

    局部标号的使用说明:

    局部标号主要在局部范围内使用,而且局部标号可以重复出现。它由两部组成:开头是一个0-99直接的数字,后面紧接一个通常表示该局部变量作用范围的符号。局部变量的作用范围通常为当前段,也可以用ROUT来定义局部变量的作用范围。

    局部变量定义的语法格式:N{routname}

    A、N:为0~99之间的数字。

    B、routname:当前局部范围的名称(为符号),通常为该变量作用范围的名称(用ROUT伪操作定义的)。

    局部变量引用的语法格式:%{F|B}{A|T}N{routname}

    A、%:表示引用操作

    B、N:为局部变量的数字号

    C、routname:为当前作用范围的名称(用ROUT伪操作定义的)

    D、F:指示编译器只向前搜索

    E、B:指示编译器只向后搜索

    F、A:指示编译器搜索宏的所有嵌套层次

    G、T:指示编译器搜索宏的当前层次

    例:使用局部符号的例子,一段循环程序

    1:

    subs r0, r0, #1 @每次循环使r0=r0-1

    bne 1F      @跳转到1标号去执行

     

    如果FB都没有指定,编译器先向前搜索,再向后搜索

    如果AT都没有指定,编译器搜索所有从当前层次到宏的最高层次,比当前层次低的层次不再搜索。

    如果指定了routname,编译器向前搜索最近的ROUT伪操作,若routname与该ROUT伪操作定义的名称不匹配,编译器报告错误,汇编失败。

    二、GNU ARM汇编程序的分段

    1GNU ARM汇编中段的定义

    GNU ARM汇编中通过.section伪操作来自定义一个段,格式如下:

    .section section_name [, "flags"[, %type[,flag_specific_arguments]]]

    Section_name:段名

    Flags: ELF格式允许的段标志: a:可分配 w:可写段 x:执行段

    Type:段类型

    flag_specific_arguments:指定参数内容

    定义一个段,每一个段以段名为开始,以下一个段名或者文件结尾为结束。

     

    2、GNU ARM汇编系统预定义的段

    .text    @代码段

    .data    @初始化数据段 .data Read-write initialized long data.

    .bss     @未初始化数据段

    .sdata   @ .sdata Read-write initialized short data.

    .sbss    @

    注意:源程序中.bss段应该在.text段之前。

    程序执行代码放于.text段,需要读写的数据放于.data段,只读数据放于.rodata段,未初始化数据放于.bss段

     

    三、GNU ARM汇编程序的入口点

    汇编程序的缺省入口是_start标号,用户也可以在连接脚本文件xxx.lds中用ENTRY标志指明其它入口点。

    例:定义入口点

    .section .data

    < initialized data here>

    .section .bss

    < uninitialized data here>

    .section .text

    .globl  _start

    _start:

    <instruction code goes here>

    四、GNU ARM汇编的宏定义

    宏定义的格式如下:

    .macro 宏名 参数名列表       @伪操作.macro定义一个宏  

     

    宏体

     

    .endm @.endm表示宏结束

    如果宏使用参数,那么在宏体中使用该参数时添加前缀“\”。宏定义时的参数还可以使用默认值。可以使用.exitm伪指令来退出宏。

    五、GNU ARM汇编中的常数

    A、十进制数以非0数字开头,:1239876
    B、二进制数以0b开头,其中字母也可以为大写;
    C、八进制数以0开始,:0456,0123
    D、十六进制数以0x开头,:0xabcd,0X123f
    E、字符串常量需要用引号括起来,中间也可以使用转义字符,: You are welcome!\n”;
    F、当前地址以“.”表示,在汇编程序中可以使用这个符号代表当前指令的地址;
    G、表达式:在汇编程序中的表达式可以使用常数或者数值, -”表示取负数, ~”表示取补,<>”表示不相等,其他的符号如:+-* /%<<<>>>|&^!==>=<=&&|| C语言中的用法相似。

     

    六、GNU ARM汇编的伪操作

    1、数据定义伪操作

    A、.byte:单字节定义,如:.byte 1,2,0b01,0x34,072,'s'
    B、.short:定义双字节数据,如:.short 0x1234,60000
    C、.long:定义4字节数据,如:.long 0x12345678,23876565
    D、.quad:定义8字节,如:.quad 0x1234567890abcd
    E、.float:定义浮点数,如:
      .float 0f-314159265358979323846264338327\
      95028841971.693993751E-40 @ - pi
    F、.string/.asciz/.ascii:定义多个字符串,如:
      .string "abcd", "efgh", "hello!"
      .asciz "qwer", "sun", "world!"
      .ascii "welcome\0"
    需要注意的是:.ascii伪操作定义的字符串需要自行添加结尾字符'\0'
    G、.rept:重复定义伪操作, 格式如下:
      .rept 重复次数
      数据定义
      .endr @结束重复定义
      例如:
      .rept 3
      .byte 0x23
      .endr
    H、.equ/.set: 赋值语句, 格式如下:
      .equ(.set) 变量名,表达式
      例如:
      .equ abc 3 @abc=3

    I、.int:定义一个整型

    语法格式:.int expressions

     

    2、.if伪操作

    根据一个表达式的值来决定是否要编译下面的代码, 用.endif伪操作来表示条件判断的结束, 中间可以使用.else来决定.if的条件不满足的情况下应该编译哪一部分代码。

    A、.ifdef label @判断label是否定义
    B.ifc string1,string2 @字符串string1string2是否相等,字符串可以用单引号括起来
    C.ifeq expression_r @判断expression_r的值是否为0
    E.ifeqs string1,string2 @判断string1string2是否相等,字符串必须用双引号括起来
    F.ifge expression_r @判断expression_r的值是否大于等于0
    G.ifgt absolute expression_r @判断expression_r的值是否大于0
    H.ifle expression_r @判断expression_r的值是否小于等于0
    I.iflt absolute expression_r @判断expression_r的值是否小于0
    J.ifnc string1,string2 @判断string1string2是否不相等, 其用法跟.ifc恰好相反。
    K.ifndef symbol, .ifnotdef symbol @判断是否没有定义symbol, .ifdef恰好相反
    L.ifne expression_r @如果expression_r的值不是0, 那么编译器将编译下面的代码
    M.ifnes string1,string2 @如果字符串string1string2不相 等, 那么编译器将编译下面的代码.

    3、操作码


    A、NOP
           nop
           空操作, 相当于MOV r0, r0
    B、LDR
              ldr <register> , = <expression>
           相当于PC寄存器或其它寄存器的长转移.
    C、ADR
              adr <register> <label>
           相于PC寄存器或其它寄存器的小范围转移.

    D、ADRL
              adrl <register> <label>
           相于PC寄存器或其寄存器的中范围转移


    4、其他伪操作

    A、.end:表明源文件的结束

    B、.extern用于声明一个外部标号

    语法格式:.extern label

    C、.global/.globl用来声明一个全局标号

    语法格式:.global/.globl label

     

    D、.zero、.space、.skip

    分配number_of_bytes字节的数据空间,.zero伪操作用0填充内存,.space/.skip用值为fill_byte填充内存,若未指定该值,缺省填充0

    语法格式:

    .zero <number_of_bytes>
    .space/.skip <number_of_bytes> {,<fill_byte>}

    E、.reg.unreq

    .reg: 用来给寄存器赋予别名,格式如下:

           别名 .req 寄存器名

    .unreq: 用来取消一个寄存器的别名,格式如下:

    .unreq 寄存器别名

    注意被取消的别名必须事先定义过,否则编译器就会报错,这个伪操作也可以用来取消系统预制的别名,

    F、.include

    语法格式:.include "filename"

    在当前源文件中展开filename的内容。

    G、.align

    用来指定数据的对齐方式

    语法格式:

    .align [absexpr1, absexpr2]
      以某种对齐方式,在未使用的存储区域填充值. 第一个值表示对齐方式,

    表示2^n字节对齐,第二个表达式值表示填充的值。

    .balignl 4 0xdeadbeef   4字节对齐,l表示以四字节单位填充,填充0xdeadbeef



    H、.incbin

    .incbin伪操作可以将原封不动的一个二进制文件编译到当前文件中,语法格式:
      .incbin "file"[,skip[,count]]
     skip表明是从文件开始跳过skip个字节开始读取文件,count是读取的字数

     

    七、GUN ARM汇编中的寄存器

    寄存器命名规范:

    通用寄存器:R0--R15

    栈指针寄存器:SP(R13)

    帧指针寄存器:FP(R11)

    链接寄存器:LR(R14)

    程序计数器:PC(R15)

    程序状态寄存器:xPSR, xPSR_all, xPSR_f, xPSR_x, xPSR_ctl, xPSR_fs,
    xPSR_fx, xPSR_f, xPSR_cs, xPSR_cf, xPSR_cx

    编程过程中对所有寄存器的赋值必须遵循AAPCS(The ARM Architecture Procedure Call Standard)。

    八、GNU ARM汇编与ARM ASM汇编语法比较

    GNU汇编器与ARM汇编器语法比较:

    GNU Assembler

    ARM ASM

    备注

    @

    ;

    注释

    #&

    #0x

    十六进制立即数

    .if

    IFDEF,IF

    不完全相同

    .else

    ELSE

     

    .elseif

    ELSEIF

     

    .endif

    ENDIF

     

    .ltorg

    LTORG

     

    |

    :OR:

    OR

    &

    :AND:

    AND

    <<

    :SHL:

    Shift left

    >>

    :SHR:

    Shift right

    .macro

    MACRO

    开始宏

    .end

    ENDM

    结束宏

    .include

    INCLUDE

     

    .word

    DCB

    A data word

    .short

    DCW

     

    .long

    DCD

     

    .byte

    DCB

     

    .req

    RN

     

    .global

    IMPORT

     

    EXPORT

     

    .equ

    EQU

    展开全文
  • GNU ARM汇编快速入门.pdf
  • GNU ARM汇编伪指令

    2010-11-30 16:42:02
    GNU ARM汇编伪指令包括ARM常规指令
  • GNU ARM汇编快速入门

    2019-01-08 00:00:55
    ARM汇编的不同之处。其实非常的简单,浏览一下文档然后再看看程序就完全可以搞定了,或者你硬着头皮看GNU ARM的汇编程序,用不了多少时间你就就可以无师自通了。 ARM汇编语言源程序语句 ,一般由指令、伪操作、...
  • 官方地址: https://sourceware.org/binutils/docs/as/ 参考资源:GNU AS汇编器官方文档
  • GNU ARM 汇编指令

    2021-05-15 18:44:49
    第一部分 Linux下ARM汇编语法尽管在Linux下使用C或C++编写程序很方便,但汇编源程序用于系统最基本的初始化,如初始化堆栈指针、设置页表、操作 ARM的协处理器等。初始化完成后就可以跳转到C代码执行。需要注意的是...
  • GNU ARM 汇编指令(注意是GNU
  • GNU ARM 汇编

    2012-05-22 22:59:00
    GNU ARM 汇编 GNU:维基百科上说:GNU,一个类UNIX的操作系统,由GNU计划推动,目标在于建立一个完全相容于UNIX的自由软件环境。这里GNU代表了一种平台,一类开发环境,更是一种汇编程序设计的语法格式。我们这里可以...
  • GNU ARM 汇编基础笔记

    千次阅读 热门讨论 2021-05-18 10:41:13
    文章目录目的汇编基础说明基础语法常用指令ARM汇编演示模拟器 VisUAL使用演示与C语言混合使用总结 目的 汇编的核心就是使用各种指令来编码完成需求,而指令这个东西其实就是最底层二进制的机器码的基础上做了一层...
  • GNU ARM汇编--(十二)arm汇编指令的B真的那么简单吗?

    千次阅读 多人点赞 2012-08-23 23:15:15
    说句题外话,在输入“指令”二字的时候,就想起了google搜索时,提示“令”不能搜索,要我换词汇.如果不能说脏话,我真就无语了. ...比如编译链接\gnu的linker script等等.也有很多地方只懂表面,没有做深入的理解.
  • GNU ARM汇编语法

    千次阅读 2014-03-14 21:15:31
    汇编源程序一般用于系统最基本的初始化:初始化堆栈指针、设置页表、操作 ARM的协处理器等。这些初始化工作完成后就可以跳转到C代码main函数中执行。  1、GNU汇编语言语句格式 任何Linux汇编行都是如下结构:[:]...
  • GNU ARM汇编--(二)汇编编译链接与运行

    万次阅读 多人点赞 2012-04-26 22:28:46
    GNU的汇编器是GNU Tools的一部分,可以用来ARM的汇编语言源代码编译为二进制文件....这里我们只是做一个简短的介绍,对GNU汇编器有一个大概的认识,同时通过两个例子了解一下GNU ARM汇编.  给出一个模板文件: .text
  • 在写GNU ARM汇编下的linker script之前,还是有必要看一下ldr指令,以及ldr和adr伪指令.  ldr指令:  LDR load word into a register Rd  ldr伪指令:  LDR Rd, =con
  • GNU ARM汇编入门

    2019-09-25 10:43:31
    第一部分 Linux下ARM汇编语法尽管在Linux下使用C或C++编写程序很方便,但汇编源程序用于系统最基本的初始化,如初始化堆栈指针、设置页表、操作 ARM的协处理器等。初始化完成后就可以跳转到C代码执行。需要注意的是...
  • ARM汇编与ARM GNU汇编 区别

    千次阅读 2019-05-10 11:14:32
    t汇编与ARM汇编的区别? 问:想学汇编语言,因为现在用的是linux系统(ubuntu11.04),so 有一本《汇编语言程序设计》马朝晖译,可惜淘宝、当当、京东等都没货,淘宝上只有盗版的。 ARM的书倒是挺多(但是我不是搞...
  • GNU ARM 汇编简介

    2015-11-10 19:50:32
    1. GNU ARM 汇编简介  任何汇编行都是如下结构: [:] [} @ comment [:] [} @ 注释    GNU ARM 汇编中,任何以冒号结尾的都被认为是一个标签,而不一定非要在一行的开始。下面是一个简单的例子,这段...
  • GNU ARM 汇编器 Usage

    2022-01-21 17:08:21
    使用不同汇编器的情况下,具体汇编实现的语法也会有部分出入,比如使用 MDK 那一套(ARM Assembler)和 GNU 那一套(GNU Assembler),汇编代码上,会有明显的不一样,这主要取决于汇编器; 本文侧重于 ARM GNU 的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 11,181
精华内容 4,472
关键字:

gnuarm汇编