ARM汇编语言程序设计.ppt_第1页
ARM汇编语言程序设计.ppt_第2页
ARM汇编语言程序设计.ppt_第3页
ARM汇编语言程序设计.ppt_第4页
ARM汇编语言程序设计.ppt_第5页
已阅读5页,还剩61页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1 第4章汇编语言程序设计 本章主要内容 1 ARM和Thumb汇编语言程序2 汇编语言与C语言3 混合编程技术4 汇编语言程序的汇编 运行 调试 2 ARM程序的源文件 1 汇编语言源文件 s 扩展名 s2 C语言源文件 c 扩展名 c3 C 源文件 cpp 扩展名 cpp4 头文件 h 扩展名 h5 引入文件 inc 扩展名 incARM程序的源文件是文本格式的文件 可以使用简单的文本编辑器或者其他的编程开发环境进行编辑 例ads1 2editword等编辑程序 4 1汇编语言源程序格式p93 3 Arm源程序汇编连接过程 例armasmhello sarmlinkhello o ohello axfarmsd exechello axf 执行之 armcc ghello s ohello axf 4 4 1 1汇编语言程序的结构p93 在ARM Thumb 汇编语言程序中 以程序段为单位组织代码 段是相对独立的指令或数据序列 具有特定的名称 段分为代码段和数据段 代码段的内容为执行代码 数据段存放代码运行时需要用到的数据 一个汇编程序至少应该有一个代码段 当程序较长时 可以分割为多个代码段和数据段 多个段在程序编译链接时最终形成一个可执行的映象文件 在汇编语言程序中 用AREA伪指令定义一个段 并说明所定义段的相关属性 5 多个代码段的情况 一个源文件只能含一个代码段并单独编译 多个代码段分别编译最后连接成映象文件 可执行映象文件的构成 一个或多个代码段 代码段的属性为只读 零个或多个包含初始化数据的数据段 数据段的属性为可读写 零个或多个不包含初始化数据的数据段 数据段的属性为可读写 6 CODE32 32位的ARM指令段 CODE1616位的thumb指令段AREAcodesec CODE READONLY 定义属性 代码段 名称为codesec 属性为只读mainPROC 函数mainSTMFDsp lr 返回地址入栈 调用main函数指令的下一条指令的地址 保存必要的寄存器和返回地址到数据栈ADRr0 strhello 取标签strhello代表的地址值BL printf 下一条指令地址送lr 转 printf 调用C运行时库的 printf函数打印 Helloworld 字符串BLwelcomefun 调用子函数welcomfunLDMFDsp pc 恢复寄存器值 返回主程序 7 Strhello strhello代表本地字符串的地址DCB Helloworld n 0 定义一段字节空间ENDP 函数main结束welcomefun 子函数welcomfunSTMFDsp lr 保存必要的寄存器和返回地址到数据栈ADRr0 adrstrarm 取adrstrarm的地址放到寄存器r0中LDRr0 r0 0 将adrstrarm的值放到r0中BL printf 调用C运行时库的 printf函数打印 WelcomtoARMworld 字符串LDMFDsp pc 恢复寄存器值 8 Adrstrarm adrstrarm标签DCDstrarm 保存strarm的地址AREAconstdatasec DATA READONLY ALIGN 0 数据段 名称为constdatasec 属性为只读strarmDCB WelcometoARMworld n 0 存放 WelcometoARMworld 字符串EXPORTmain 导出main函数供外部调用 引入三个C运行时库函数和ARM库IMPORT mainIMPORT mainIMPORT printfIMPORT Lib Request armlib WEAKEND 程序结束编译连接运行 编译连接运行 rtf 9 4 1 2汇编语言行的构成ARM Thumb汇编语言程序的语句由4部分组成 标签 指令 伪操作 伪指令操作数 语句的注释 例 welcomefunSTMFDsp lr strarmDCB WelcometoARMworld n 0 Labeladdaddr0 r0 r1 Str1SETS Thisisastring BKPT 断点标签 welcomefun strarm Labeladd Str1指令 伪操作 伪指令 STMFD DCB add SETS操作数 其他部分 10 注意 ARM程序中 指令 伪指令 伪操作 寄存器助记符可以全部为大写或小写 但大小写不能混合使用 ARM程序中的符号符号包括变量 标号 局部标号和数字常量 符号是变量 标号时又代表其地址 符号命名规则 由大小写字母 数字和下划线组成 且字母区分大小写 除局部标号以数字开头外 其他符号不能以数字开头 符号不能与助记符重名 且在其作用范围内唯一 符号一般以字母开头 由字母 数字 下划线组成 例 a12x1x2注意如果符号与ARM指令的指令名称或者伪操作名称同名时 可以用双竖线把符号括起来 如 add 11 汇编语言程序的语句4个组成部分 1 标签标签是一个符号 可以代表 指令的地址 标号 变量 数据的地址 变量名 LCLA LCLL和LCLS定义局部量GBLA GBLL和GBLS定义全局量DCBDCWDCDect定义数据地址 标号标号代表可执行语句地址 标号按其作用域可分为段内标号和和段外标号 段内标号的地址值在汇编时确定 例welcomefun段外标号的地址值在链接时确定 例EXPORTmain段外调用 BLmain 12 注意 p96 1 基于pc的标号 程序相对寻址 段内标号常用于表示转移目标地址 位于将要跳转到的指令之前 汇编时被处理成pc值加减一个常量 例 loopSUBSr0 r0 1 每次循环使r0 r0 1BNEloop 跳转到01标号去执行 2 基于寄存器的标号通常用MAP和FIELD伪操作定义之 汇编时被处理成寄存器的值加减一个常量 MAP0 xF10000 定义结构化内存表countFIELD4xFIELD4yFIELD4 13 局部标号 用于局部范围的代码 由数字0 99 N 和一个表示该局部标号作用范围的字符组成 语法格式 N routname 例 01NAMERoutname由ROUT伪操作定义其作用范围 局部标号引用格式 例 BNE B01NAME F B A T N routname 其中 表示局部标号引用操作F指示编译器只向前搜索forward 默认B指示编译器只向后搜索backwardA指示编译器搜索宏的所有嵌套层次 T指示编译器搜索宏的当前层 A T缺省 从当前层搜索到最高层 14 使用局部标号的例子 例2作用范围字符为NAMEROUTNAME NAME作用范围01NAMESUBSr0 r0 1 每次循环使r0 r0 1BNE B01NAME 跳转到01NAME标号去执行 02NAMELDRR0 R1 NAME作用范围ROUTNEXT 例1无作用范围字符01SUBSr0 r0 1 每次循环使r0 r0 1BNE B01 跳转到01标号去执行 15 2 指令 伪操作 伪指令p96 指令 表示ARM的处理器执行的操作 伪操作 由汇编程序处理的操作 为程序的汇编做准备 伪指令 汇编时被替换成机器指令 在程序执行时被执行 例 ADR ADRL LDR NOP伪指令 16 3 操作数p97 伪操作 伪指令中的操作数可以是一个常量 变量或一个由常量 符号和操作符组成的表达式 1 常量程序中的常量是指其值在程序的运行过程中不能被改变的量 类型 a 数字常量数字常量有3种表示方式 十进制数 如1 2 123十六进制数 如0 x123 0 xabcn进制数 形式为 n XXX n的范围是2到9 XXX是具体数字 如 2 1010 17 B 字符 字符串常量字符常量 由单引号及中间的字符组成 包括C语言中的转义字符 如 a n 字符串常量 由双引号及中间的字符串组成 包括C语言中的转义字符 如 abcdef 0 xa r n 转义字符 18 C 逻辑常量 TRUE FALSE 注意带大括号 2 变量变量类型 数字变量 逻辑变量和串变量 GBLAGBLLGBLS和LCLALCLLLCLS分别定义全局 局部的数字变量 逻辑变量和串变量 SETASETLSTES为其赋值 19 汇编程序的变量代换p97 字符串变量在字符串变量的前面有一个 字符 在汇编时编译器将用该字符串变量的内容代替该串变量 例 str1 取其内容例1 LCLSstr1 定义局部串变量LCLSstr2str1SETS book 赋值str2SETS Itisa str1 赋值则在汇编后 str2的值为 Itisabook 20 数字变量在数字变量前面加 编译器会将该数字变量的值转换为十六进制的字符串 例如 No1SETA10 No1数字变量Str1SETS Thenumberis No1 则汇编后Str1的值为 Thenumberis0000000A 字符加入到字符串遇到 编译器将不进行变量代换 而是把 看作一个 例如 StrSETS Thecharacteris 则编译后Str字符串的值为 Thecharacteris 21 变量名 使用 表示字符串中变量名的结束 str2SETS num1 ccc 变量名是num1num1是数字变量 str2的内容为 num1的内容转换成十六进制数后拼接ccc 一般的 在两个 之间的 并不进行变量的代换 但如果 在双引号内 则将进行变量代换 22 综合实例p98 AREA text CODE READONLY 代码段 名称为 text 属性为只读GBLSstr1 声明str1为全局字符串变量GBLSstr2 声明str2为全局字符串变量GBLLll 声明l1为全局逻辑变量GBLAnum1 声明num1为全局数字变量llSETL TRUE num1SETA0 x4fstr1SETS bbb Str2SETS aaastr1 str1 l1 l1 a1 num1 ccc str2包含了多个变量编译被替换后的Str2 aaastr1 bbbl1 T a1 0000004Fccc 23 mainPROC 函数mainSTMFDsp lr 返回地址入栈ADRr0 strhello 取strhello的地址至r0BL printf 调用C的 printf函数打印字符串LDMFDsp pc 返回Strhello strhello代表本地字符串的地址DCB str2 n 0 定义字节空间 赋值str2的内容ENDP 函数main结束EXPORTmain 导出main函数供外部调用 引入三个C运行时库函数和ARM库IMPORT mainIMPORT mainIMPORT printfIMPORT Lib Request armlib WEAKEND 24 4 1 3伪操作 在ARM汇编语言程序里 有一些特殊指令助记符 这些助记符与指令系统的助记符不同 没有相对应的操作码 通常称这些特殊指令助记符为伪操作 伪操作在源程序中的作用是为完成汇编程序作各种准备工作的 这些伪操作仅在汇编过程中起作用 一旦汇编结束 伪操作的使命就完成 在ARM的汇编程序中 伪操作共计42条 1 符号定义伪操作 变量定义 赋值10条 2 数据定义伪操作 存储区定义 赋值9条 3 汇编控制伪操作6条 4 其他伪操作17条 25 符号定义伪操作 用于变量定义 赋值共计10条 LCLA LCLL LCLS 局部变量定义 GBLA GBLL GBLS 全局变量定义 SETA SETL SETS 变量赋值 RLIST 通用寄存器列表定义名称 26 LCLA LCLL LCLS定义局部变量 LCLA LCLL LCLS定义局部变量LocalarithmeticLocallogicLocalstring格式 LCLA LCLL LCLS局部变量名说明 LCLA LCLL LCLS伪操作用于定义一个汇编程序中的局部变量 并初始化 其中 LCLA定义一个局部的数字变量 初始化为0 LCLL定义一个局部的逻辑变量 初始化为F LCLS定义一个局部的字符串变量 初始化为空串 27 这三条伪指令用于声明局部变量 在其局部作用范围内变量名必须唯一 例如 在宏内 局部变量一般仅用于宏中 例如 MACROTESTLCLAnum1 声明一个局部的数字变量 变量名为num1LCLLl2 声明一个局部的逻辑变量 变量名为l2 LCLSstr3 定义一个局部的字符串变量 变量名为str3num1SETA0 xabcd 将该变量赋值为0 xabcdl2SETL FALSE 将该变量赋值为真str3SETS Hello 将该变量赋值为 Hello 使用局部变量MEND在宏内定义局部变量后 在宏外使用该变量时编译会出错 宏引用 TEST 28 GBLA GBLL GBLS定义全局变量 格式 GBLA GBLL GBLS变量名说明 GBLA GBLL GBLS伪操作定义一个汇编程序中的全局变量 并初始化 其中 GBLA定义一个全局数字变量 并初始化为0 GBLL定义一个全局逻辑变量 并初始化为 F GBLS定义一个全局字符串变量 并初始化为空串 这三条伪指令用于定义全局变量 因此在整个程序范围内变量名必须唯一 29 例如 GBLAnum1 定义一个全局的数字变量 变量名为num1num1SETA0 xabcd 将该变量赋值为0 xabcdGBLLl2 定义一个全局的逻辑变量 变量名为l2l2SETL FALSE 将该变量赋值为假GBLSstr3 定义一个全局的字符串变量 变量名为str3str3SETS Hello 将该变量赋值为 Hello 30 SETA SETL SETS变量赋值 格式 变量名SETA SETL SETS表达式说明 SETA 给一个数字变量赋值 SETL 给一个逻辑变量赋值 SETS 给一个字符串变量赋值 格式中的变量名必须为已经定义过的全局或局部变量 表达式为将要赋给变量的值 例如 LCLAnum1 声明一个局部的数字变量num1num1SETA0 x1234 将该变量赋值为0 x1234LCLSstr3 声明一个局部的逻辑变量str3str3SETS Hello 该变量赋值为 Hello 31 RLIST 格式 名称RLIST 寄存器列表 说明 RLIST可用于对一个通用寄存器列表定义名称 该名称可在ARM指令LDM STM中使用 在LDM STM指令中 列表中的寄存器根据寄存器的编号确定其访问次序 与列表中的寄存器排列次序无关 低编号寄存器对应低地址存储单元 高编号寄存器对应高地址存储单元 32 例如 PblockRLIST R0 R3 R7 R5 R9 将寄存器列表名称定义为pblock 可在ARM指令LDM STM中通过该名称访问寄存器列表 STMFDSP pblock 由高到低访问 R9先入栈STMFASP pblock 由低到高访问 R0先入栈STMSP pblock 出错 33 数据定义伪操作 数据定义伪操作用于存储区定义 赋值 共计9条 DCBDCW DCWUDCD DCDUDCQ DCQUDCFS DCFSUDCFD DCFDUSPACEFIELDMAP 34 DCB定义字节 Definecontinuebytes定义字节格式 标号DCB表达式说明 DCB分配连续的字节单元并用伪操作中指定的表达式对其初始化 其中 表达式可以为使用双引号的字符串或0 255的数字 DCB可用 代替 35 例如 Array1DCB1 2 3 4 5 数组str1DCB Yourarewelcome 构造字符串并分配空间 或str1 Yourarewelcome LDRR0 Array1 大范围地址读取 4G 取Array1地址至R0 36 DCW DCWU定义半字 格式 标号DCW DCWU表达式说明 DCW分配连续半字存储单元并用表达式值初始化 它定义的存储空间是半字对齐的 DCWU功能跟DCW类似 只是分配的存储单元不严格半字对齐 例如 Arrayw1DCW0 xa 0 xb 0 xc 0 xd 构造固定数组并分配半字存储单元 37 DCD DCDU定义字 格式 标号DCD DCDU表达式说明 DCD伪操作分配连续的字存储单元并用伪指令中指定的表达式初始化 它定义的存储空间是字对齐的 DCD也可用 该字单元存放str1的地址 38 DCQ DCQU定义8字节 DCQ DCQU格式 标号DCQ DCQU表达式说明 DCQ用于分配一块以8个字节为单位的存储区域并用指定的表达式初始化 它定义的存储空间是字对齐的 DCQU功能跟DCQ类似 只是分配的存储单元不严格字对齐 例如 Arrayd1DCQ234234 98765541 构造固定数组并分配字为单元的存储空间注意DCQ不能给字符串分配空间 39 DCFD DCFDU定义浮点数 DCFD DCFDU双精度的浮点数 8个字节 格式 标号DCFD DCFDU表达式说明 DCFD用于为双精度的浮点数 8个字节 分配一片连续的字存储单元并用伪指令中指定的表达式初始化 它定义的存储空间是字对齐的 每个双精度的浮点数占据两个字单元 DCFDU功能跟DCFD类似 只是分配的存储单元不严格字对齐 例如 Arrayf1DCFD6E2Arrayf2DCFD1 23 1 45 40 DCFS DCFSU定义单精度的浮点数 4个字节 格式 标号DCFS DCFSU表达式说明 DCFS用于为单精度的浮点数 4个字节 分配一片连续的字存储单元并用表达式初始化 它定义的存储空间是字对齐的 每个单精度浮点数使用一个字单元 DCFSU功能跟DCFS类似 只是分配的存储单元不严格字对齐 例如 Arrayf1DCFS6E2 9E 2 3Arrayf2DCFSU1 23 6 8E9 41 SPACE定义存储区域 格式 标号SPACE表达式说明 SPACE用于分配一片连续的存储区域并初始化为0 表达式为要分配的字节数 SPACE也可用 代替 例如 freespaceSPACE1000 分配1000字节的存储空间 使用已分配空间 adrr0 freespace或ldrr0 freespacestrr1 r0 42 MAP定义内存表首地址 MAP定义一个结构化的内存表的首地址 与FIELD伪操作配合使用来定义结构化的内存表 语法格式 MAP表达式 基址寄存器 内存表的首地址 基址寄存器 表达式MAP可以与FIELD伪操作配合使用来定义结构化的内存表 例如 MAP0 x130 R2 内存表首地址为 R2 0 x130 43 FILED 格式 标号FIELD字节数说明 FIELD用于定义一个结构化内存表中的数据域 可用来代替FILED 需要注意的是MAP和FIELD伪指令仅用于定义数据结构 并不分配存储单元 错误 定义数据结构 分配存储单元 例如 MAP0 xF10000 定义结构化内存表首地址为0 xF10000 countFIELD4 count的长度为4字节 位置为0 xF10000 xFIELD4 x的长度为4字节 位置为0 xF10004yFIELD4 y的长度为4字节 位置为0 xF10008 44 引用内存表中的数据 LDRR0 count conut的地址送R0STRR1 R0 LDRR1 R0 45 汇编控制伪操作 汇编控制伪操作用于指引汇编程序的执行流程 常用的伪操作包括以下几种 MACRO MENDIF ELSE ENDIFWHILE WENDMEXIT 46 MACRO MEND定义宏的开始和结束 宏定义格式 MACRO 标号 宏名 参数1 参数2 指令序列MEND说明 MACRO表明一个宏定义的开始 MEND则表示一个宏的结束 MACRO MEND前呼后应可以将一段代码定义为一个整体 又称宏 然后就可以在程序中通过宏的名称及参数调用该段代码 标号是一个可选的参数 在宏指令被展开时 标号会被替换为用户定义的符号 宏指令使用一个或多个参数 当宏被展开时 这些参数被相应的值替换 这些值可以是寄存器 47 例宏定义 MACRO labelmysub2 p1 p2SUBp1 p2 2MEND程序中调用宏 BEGINmysub2R0 R1 宏调用展开 SUBR0 R1 2在源程序被编译时 汇编器将宏调用展开 用宏定义中的指令序列替换程序中的宏调用 并将实际参数的值传递给宏定义中的参数 宏操作可以嵌套使用 并可以在编译时用选项加以控制 48 IF ELSE ENDIF条件编译 格式 IF逻辑表达式代码段1ELSE代码段2ENDIF说明 如果IF后面的逻辑表达式为真 则编译代码段1 否则编译代码段2 ELSE及代码段2也可以没有 这时 当IF后面的逻辑表达式为真 则代码段1 否则继续编译后面的指令 IF ELSE ENDIF可以分别用 代替 IF ELSE ENDIF伪指令可以嵌套 49 例如 GBLLisbig 声明一个全局的逻辑变量 变量名为isbigisbigSETLTRUE 或FALSE逻辑变量赋值IFisbig TRUEaddr0 r0 1ELSEsubr0 r0 1ENDIF 50 WHILE WEND循环汇编 格式 WHILE逻辑表达式代码段WEND说明 WHILE WEND伪指令能根据条件的成立与否决定是否汇编某个指令序列 当WHILE后面的逻辑表达式为真 则汇编指令序列 该指令序列汇编后 再判断逻辑表达式的值 若为真则继续汇编 一直到逻辑表达式的值为假 WHILE WEND伪指令可以嵌套使用 51 例如 GBLAnum 声明全局的数字变量numnumSETA9 由num控制循环次数 WHILEnum 0subr0 r0 1addr1 r1 1numSETAnum 1WEND 52 MEXIT从宏中退出 语法格式 MEXIT说明 MEXIT用于从宏中退出 53 其他伪指令 ASSERTAREAALIGNCODE16 CODE32ENTRYENDEQUIMPORTEXPORT GLOBAL EXTERNINCBINGET INCLUDERNROUT 54 ASSERT 格式 ASSERT逻辑表达式说明 ASSERT用来表示程序的编译必须满足一定的条件 如果逻辑表达式不满足 则编译器会报错 例如 ASSERTver 7 保证ver 7 55 AREA定义一个段 格式 AREA段名属性 属性 说明 1 AREA用于定义一个代码段 数据段或者特定属性的段 2 如果段名以数字开头 那么该段名需用 字符括起来 如 7wolf 3 属性部分表示该代码段 数据段的相关属性 多个属性可以用 分隔 常见属性如下 1 DATA 定义数据段 2 CODE 定义代码段 3 READONLY 表示本段为只读 56 4 READWRITE 表示本段可读写 5 ALIGN 表达式表达式的取值范围为0 31 对齐方式为2的表达式次方 例如 表达式 3 则对齐方式为8字节对齐 6 COMMON属性 定义一个公用段 这个段不包含用户代码和数据 各源文件中同名的COMMON段共享同一段存储单元 连接器为其分配合适的尺寸 例如 AREAtest CODE READONLYAREA text CODE READONLY没有段结束伪指令 57 ALIGN对齐 ALIGN伪操作可以通过填充字节使当前的位置满足一定的对齐方式 1 ALIGN 表达式其中 表达式的值为2的幂 如1 2 4 8 16等 用于指定对齐方式 例如 AREA data DATA READWRITE ALIGN 2 指定后面的指令为4字节对齐 2 ALIGN 表达式 偏移量 偏移量也是个数字表达式 如果存在偏移量 则当前位置的自动对齐到 表达式值 偏移量 例ALIGN8 指定后面的指令为8字节对齐 如果伪操作中没有指定表达式 则编译器会将当前位置对齐到下一个字的位置 58 CODE16 CODE32 格式 CODE16 CODE32说明 CODE16伪操作指示编译器后面的代码为16位的Thumb指令 CODE32伪操作指示编译器后面的代码为32位的ARM指令 在使用ARM指令和Thumb指令混合编程的代码里 这两条伪指令后面的代码类型是不同的 但它们并不能对处理器进行状态的切换 59 例如 CODE32 32位的ARM指令AREA text CODE READONLY LDRR0 THU 取THU地址ORRR0 R0 1 新增BXR0 程序跳转 并将处理器切换到Thumb状态 CODE16 16位的Thumb指令THUADDR3 R2END 源文件结束 60 ENTRY指定程序入口 格式 ENTRY说明 ENTRY用于指定汇编程序的入口 在一个源文件里可以有一个ENTRY或者没有ENTRY 若无ENTRY 必须加标号 61 例 AREAsubrout COD

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论