Assembly 理解ARM向量表汇编声明的语法

Assembly 理解ARM向量表汇编声明的语法,assembly,linker,arm,Assembly,Linker,Arm,我正在自学一些ARM汇编,并且正在努力寻找描述重置向量表声明的特定形式的资源 CODE32 Vector_Table reset_vector b reset_handler undefined_exception b reset_handler svc_exception b reset_handler etc... 我感到困惑的是“Vector_Table”语句的使用,乍一看,我认为它是一个标签,但在查看文档后,我意识到标签以“:”结尾。以前有没有人看过这个表单,

我正在自学一些ARM汇编,并且正在努力寻找描述重置向量表声明的特定形式的资源

CODE32
Vector_Table

reset_vector
    b reset_handler
undefined_exception
    b reset_handler
svc_exception
    b reset_handler
etc...
我感到困惑的是“Vector_Table”语句的使用,乍一看,我认为它是一个标签,但在查看文档后,我意识到标签以“:”结尾。以前有没有人看过这个表单,可以解释一下语法?我在谷歌搜索中找不到任何有用的东西


我天真的猜测是,链接器会将“Vector_Table”和“reset_Vector”符号分配到同一地址,这样它们就等于第一条分支指令。

它们实际上是英特尔语法中的标签(Keil,armasm)
标签以
AT&T语法中的
结尾(GCC、LLVM等)

这些
b
指令只是每个中断/异常向量的空格持有者。

这些都是标签:

Vector_Table
reset_vector
reset_handler
undefined_exception
svc_exception
汇编语言特定于工具,而不是目标(ARM)。一些汇编器(对于ARM或一般来说)不使用冒号来标记标签,其他汇编器使用冒号,其他汇编器有不同的解决方案。请注意,这与英特尔、AT&T和x86没有任何关系。汇编作者完全可以自由地发明任何他们想要的语言,只要它能产生可用的机器代码(好吧,它甚至不必这样做,但如果你不能用它编写程序,它会有多大用处)

ARM本身至少有三代(如果不是更多的话)装配师,他们在不久前收购了Keil,Keil在MCU和多个目标方面很强大,是许多公司和政府机构使用的专业工具中的大牌之一(他们宁愿花很多钱来拥有一个电话号码,他们可以打电话寻求支持,而不是一个免费的工具,他们无法轻易获得相同级别的支持)我使用了至少三代来自ARM的工具,但不再具有访问权限,而且根本没有使用Keil工具,我怀疑他们的工具已经用一种ARMs的风格进行了交换。当您执行程序时,GNU的汇编程序被称为本机目标,因此GNU汇编程序通常被缩短为gas。Llvm没有汇编程序Llvm是gnu在免费工具选项方面的主要竞争对手,clang是他们的主要C编译器,不幸的是,也是他们的汇编程序,声称支持gnu对事物的解释,尽管正如堆栈溢出问题所显示的,这方面存在漏洞

汇编语言的变体不限于或特定于指令

mov r0,r1
您会发现其中的差异,但有时您会发现语言中的大部分差异是非指令区域,如标签、注释、数据声明(.byte、DB等),宏等。ARM中的经典工具在堆栈溢出中有很多,没有GNU assembler那么多,但仍然足够了,没有像GNU assembler中那样使用大量的冒号和句点标签:,.section.text、.word等。历史上,许多用于各种目标的汇编语言都使用分号;对于commGNU assembler for ARM使用at符号@。冒号是一种在每行mov r0,r1中添加多条指令的方法;添加r3,r0,r3,这在许多其他汇编语言中是闻所未闻的

将其称为向量表是误导性的,因为它是这一代/风格的ARM处理器的例外表,而不是向量。您在神奇的地址执行指令,但找不到向量(地址),这通常意味着您需要使用b指令(分支)或ldr pc,标签在一条指令中从4字节表位置分支。异常表和处理程序记录在ARM体系结构参考手册中,如果没有参考,您应该从armv5版本开始。如果您的问题与标签严格相关,则您可能已经获得了该信息在阅读或编写汇编语言之前使用文档

作为标签,yes Vector_Table和reset_Vector的地址与写入的地址相同

使用GNU汇编程序(gas),语法如下:

.code 32
Vector_Table:

reset_vector:
    b reset_handler
undefined_instruction:
    b reset_handler
    
当链接时

    Disassembly of section .text:

00000000 <Vector_Table>:
   0:   ea000000    b   8 <reset_handler>

00000004 <undefined_instruction>:
   4:   eaffffff    b   8 <reset_handler>

00000008 <reset_handler>:
   8:   eafffffe    b   8 <reset_handler>
在这种情况下,Vector_Table和reset_Vector位于同一地址,对于异常表的低/正常位置,该地址将为0x00000000

如果另一个汇编器或具有此汇编器的工具链具有与GNU binutils相同的丰富工具,或者文件格式是您可以使用binutils的,那么您还可以检查这些工具产生了什么,并看到这些相同的东西

虽然这个链接在某个时候可能会过时,但谷歌很容易找到一个例子

注释的分号标签上没有冒号等

请注意,如果您必须前后移植,我倾向于使用;@在行的末尾标记注释,以便它适用于两种语言。您还需要移植.YMMV


有趣的是,同样的代码块可以追溯到ARM ADS(早于ADT和RealView工具的ARM开发者套件),这也是你可以在谷歌上看到ARM ADS工具文档的东西,包括语法。

AT&T语法是x86的东西,而不是ARM的东西。带有:的标签是一种气体,叮当作响的东西(GCC是一个编译器,LLVM没有汇编程序,它使用的是编译器clang)。b指令是处理程序的入口点,要从表中退出,您可以使用b或ldr pc,label。同样,Intel语法也与此无关,这些概念早于x86以及AT&T制造的混乱。Keil是否支持x86?在被ARM购买之前,它在其他处理器方面表现出色…armasm never支持Intel这是肯定的…Intel语法和AT&T语法都使用冒号,或者至少当前支持上述变体的主要竞争工具都支持冒号作为标签。如果y
00000008 t reset_handler
00000000 t reset_vector
00000004 t undefined_instruction
00000000 t Vector_Table
        AREA     ARMex, CODE, READONLY
                                ; Name this block of code ARMex
        ENTRY                   ; Mark first instruction to execute
start
        MOV      r0, #10        ; Set up parameters
        MOV      r1, #3
        ADD      r0, r0, r1     ; r0 = r0 + r1
stop
        MOV      r0, #0x18      ; angel_SWIreason_ReportException
        LDR      r1, =0x20026   ; ADP_Stopped_ApplicationExit
        SVC      #0x123456      ; ARM semihosting (formerly SWI)
        END                     ; Mark end of file