1、ARM 嵌入式系统结构与 编程 第 2 版, 邱铁 编著. 清华大学出版社. 2013 年 8 月第 2 版 ,2015 年 8 月第 4 次印 刷 ARM 嵌 入 式 系统 结 构 与 编 程 第 2 版,第 68 章 思 考与 练习 题 答案 ( 此答 案仅 供教 师教 学用 ) 第 6 章 ARM 汇 编 伪 指 令 与 伪 操作 思 考与 练习 题 答案 1 在ARM 汇编语言程序设计 中,伪操作与伪指令 的区 别是什么? 解答: 伪指令 是 ARM 处理 器支 持的 汇 编语 言程 序里 的特 殊助记 符,它 不 在处 理 器 运 行期间 由机 器执 行, 只是 在 汇编时 将被 合
2、适 的机 器指 令代替 成 ARM 或 Thumb 指令, 从而实 现真 正的 指令 操作 。 伪操作(Directive) 是ARM 汇编语 言程 序里 的一 些特 殊的指 令助 记符,其 作用 主 要 是 为 完 成 汇 编 程 序 做 各 种 准 备 工 作, 对 源 程 序 运 行 汇 编 程 序 处 理, 而 不 是 在 计 算 机 运 行期间 由处理器执行.也就 是说,这些伪操作只是汇编 过程中起作用, 一旦汇编结 束,伪 操作也 就随 之消 失 。 2 分析 ARM 汇编语言伪指令 LDR 、ADRL 、ADR 的汇编结 果,说明它们之间的 区 别。 解答: 见教 材 6.1 节
3、 的详 细描述 。 3 在ADS 编译环境下,写出 实现下列操作的伪操 作: (1 )声明一个局部 的算术 变量 La_var1 并将其初始 化为 0 ; (2 )声明一个局部 的逻辑 变量 Ll_var 并将其初始化 为 FALSE ; (3 )声明一个局部 的字符 串变量 Ls_var 并将其初始 化为空串 ; (4 )声明一个全局 的逻辑 变量 Gl_var 并将其初始化 为 FALSE ; (5 )声明一个全局 的字符 串变量 Gs_var 并将其初始 化为空串 。 (6 )声明一个全局 的算术 变量 Ga_var 并将其赋值 为 0xAA ; (7 )声明一个全局 的逻辑 变量 Gl
4、_var 并将其赋值 为 TURE ; (8 )声明一个全局 的字符 串变量 Gs_var 并将其赋值 为“CHINA”。 解答: (1 )LCLA La_var1 ; ARM 嵌入式系统结构与 编程 第 2 版, 邱铁 编著. 清华大学出版社. 2013 年 8 月第 2 版 ,2015 年 8 月第 4 次印 刷 (2 )LCLL Ll_var ; (3 )LBLS Ls_var ; (4 )GBLL Gl_var ; (5 )GBLS Gs_var ; (6 ) GBLA Ga_var Ga_var SETA 0xAA (7 ) GBLL Gl_var Gl_var SETL TURE
5、(8 ) GBLS Gs_var Gs_var SETS “CHINA” 4 有ARM ADS 伪操作将寄存器列表 R0-R5、R7、R8 的名称定义为 Reglist。 解答: Reglist RLIST R0-R5,R7,R8 5 在ARM 标准 ADS 编译环境 下 完成下列数据定义 伪操 作: (1 ) 申请以 data_buffer1 为起 始地址的连续的内存 单元 , 并用依次用半字数 据 0x11,0x22,0x33,0x44,0x55 进行初始化; (2 ) 申请 以 Str_buffer 为起始地址 的连续的 内存单元 ,并用 字符串 “ARM7 and ARM9 ” 进行初
6、始化 解答: (1) data_buffer1 DCW 0x11,0x22,0x33,0x44,0x55 (2) Str_buffer DCB “ARM7 and ARM9” 6 定义一个结构化的内 存表 ,其首地址固定为 0x900 ,该结构化内存表包 含 2 个域,Fdata1 长度为 8 个字节,Fdata2 长度为 160 个字节。 解答: MAP 0x900 Fdata1 FIELD 8 ; Fdata2 FIELD 160 ; 7 在GNU 编译 环境 下, 写出 实现下 列操 作的 伪操 作: (1) 分配 一段 字节 内存 单 元,并 用57, 0x11, 031, Z,0x7
7、6进 行初 始化 ; ARM 嵌入式系统结构与 编程 第 2 版, 邱铁 编著. 清华大学出版社. 2013 年 8 月第 2 版 ,2015 年 8 月第 4 次印 刷 (2) 分配 一段 半字 内存 单 元,并 用0xFFE0 ,0xAABB ,0x12, 进行 初始 化; (3) 分配 一段 字内 存单 元 ,并用 0x12345678 ,0xAABBCCDD 进 行初 始化 ; (4) 分配 一段 内存 单元 , 并用长为8 字节 的数 值0x11 填充100次。 解答: (1 ) .byte 57, 0x11, 031, Z ,0xt6 (2 ) .hword 0xFFE0 ,0xA
8、ABB , 12 或 .short 0xFFE0 ,0xAABB , 12 (3 ) .word 0x12345678 ,0xAABBCCDD 或 .int 0x12345678 ,0xAABBCCDD 或 .long 0x12345678 ,0xAABBCCDD (4 ) .fill 100 ,8 ,0x11 8 写出与 GNU 编译环下伪操 作.arm、.thumb 功能相同 的 ADS 编译环境下的伪 操作。 解答: ARM 或 CODE32 THUMB 或 CODE16 ARM 嵌入式系统结构与 编程 第 2 版, 邱铁 编著. 清华大学出版社. 2013 年 8 月第 2 版 ,20
9、15 年 8 月第 4 次印 刷 第 7 章 汇编语言 程 序设计 思 考与 练习 题 答案 1 分别写出 ARM 集成开发 环境下 ARM 汇编语句格 式与 GNU ARM 环境下 ARM 汇编语句通用格式, 并分 析它们的区别。 解答: (1)ADS 环境 下 ARM 汇编 语句 格式 如下 : symbol instruction ;comment symbol directive ;comment symbol pseudo-instruction ;comment (2 )GNU 环境 下 ARM 汇编语 言语 句格 式如 下: label : instruction comment
10、 label : directive comment label : pseudo-instruction comment 2 局 部 标 号 提供 分 支指 令 在汇 编 程 序 的局 部 范围 内 跳转 , 它 的 主要 用 途是 什 么, 并举一实例加以例说 明。 解答: ARM 汇 编语 言的 局部 标号 是相对 全局 标号 而言 的。 局 部标号 提供 分支 指令 在汇 编程序的局部范围内跳转 ,主要用途是汇编子程序 中的循环和条件编码。它 是一个 099 之 间的数 字, 后面 可 以有选 择的 附带 一个 符号 名称。 使 用 ROUT 指示 符可以 限 制局部 标号 的范 围,
11、 从而 做到只 能在 该范 围内 引 用 局 部标号。如果在该范围的 上下两个方向都没有匹配 的标号,汇编器将给出一 个错误 信号并 停止 汇编 。 举例: 1: b 2f 2: b 1b 3 先 对 内 存 地 址 0xB000 开始的 100 个 字 内 存 单 元 填 入 0x100000010x10000064 字 数据 , 然 后将每 个字 单元 进行 64 位累加结 果 保存 于R9:R8。( R9 中 存放 高 32 位) 解答: 程序代码如下: (1) 在 GNU ARM 开发环境下编程: ARM 嵌入式系统结构与 编程 第 2 版, 邱铁 编著. 清华大学出版社. 2013
12、年 8 月第 2 版 ,2015 年 8 月第 4 次印 刷 .global _start .text .arm _start: MOV R0 , #0xB000 MOV R1 , #0x10000001 MOV R2 , #100 loop_1: STR R1 , R0,#4 ADD R1 , R1,#1 SUBS R2 , R2,#1 BNE loop_1 MOV R0 , #0xB000 MOV R2 , #100 MOV R9 , #0 MOV R8 , #0 loop_2: LDR R1 , R0,#4 ADDS R8 , R1,R8 ADC R9 , R9 , #0 SUBS R2
13、 , R2 , #1 BNE loop_2 Stop: B Stop .end (2) 在 ARM 集成开发环 境下编程 : AREA Fctrl, CODE, READONLY ENTRY CODE32 START MOV R0,#0xB000 MOV R1,#0x10000001 MOV R2,#100 loop_1 STR R1,R0,#4 ADD R1,R1,#1 SUBS R2,R2,#1 BNE loop_1 ARM 嵌入式系统结构与 编程 第 2 版, 邱铁 编著. 清华大学出版社. 2013 年 8 月第 2 版 ,2015 年 8 月第 4 次印 刷 MOV R0,#0xB0
14、00 MOV R2,#100 MOV R9,#0 MOV R8,#0 loop_2 LDR R1,R0,#4 ADDS R8,R1,R8 ADC R9,R9,#0 SUBS R2,R2,#1 BNE loop_2 Stop B Stop END (3). 程序执行后输出结果 如下 : R8= 0X400013BA R9= 0X00000006 4 在 GNU 环境下用 ARM 汇编语言编写程序初始 化各 ARM 处理器各模式下的 堆 栈指针 SP_mode(R13) ,各模式的堆栈地址如下 : .equ _ISR_STARTADDRESS, 0xcFFF000 设置栈的内存基地址 .equ U
15、serStack, _ISR_STARTADDRESS 用户模式堆栈地址 .equ SVCStack, _ISR_STARTADDRESS+64 管理模式堆栈地址 .equ UndefStack, _ISR_STARTADDRESS+64*2 未定义模式堆 栈地 址 .equ AbortStack, _ISR_STARTADDRESS+64*3 中止模式堆栈地 址 .equ IRQStack, _ISR_STARTADDRESS+64*4 IRQ 模式堆栈地 址 .equ FIQStack, _ISR_STARTADDRESS+64*5 FIQ 模式堆栈地址 解答:( 参考程序) .equ _
16、ISR_STARTADDRESS, 0XCFFF000 设置 栈的 内存 基地 址 .equ UserStack, _ISR_STARTADDRESS 用户 模式 堆栈 地址 .equ SVCStack, _ISR_STARTADDRESS+64 管理 模式 堆栈 地址 .equ UnderfStack, _ISR_STARTADDRESS+64*2 未定 义模 式堆 栈地 址 .equ AbortStack, _ISR_STARTADDRESS+64*3 中止 模式 堆栈 地址 .equ IRQStack, _ISR_STARTADDRESS+64*4 IRQ 模 式堆 栈地 址 .equ
17、FIQStack, _ISR_STARTADDRESS+64*5 FIQ 模式堆 栈地址 .equ USERMODE, 0X10 用户 模式 .equ SVCMODE, 0X13 管理 模式 ARM 嵌入式系统结构与 编程 第 2 版, 邱铁 编著. 清华大学出版社. 2013 年 8 月第 2 版 ,2015 年 8 月第 4 次印 刷 .equ UNDEFMODE, 0X1B 未定 义模 式 .equ ABORTMODE, 0X17 中止 模式 .equ IRQMODE, 0X12 IRQ 模式 .equ FIQMODE, 0X11 FIQ 模式 .equ MODEMASK, 0X1F 模
18、式 位掩 码 .global start .text start: MRS R0, CPSR BIC R0, R0, #MODEMASK #设置 管理 模式 下的 SP ORR R1, R0, #SVCMODE MSR CPSR_c, R1 进入 管理 模式 LDR SP, =SVCStack #设置 未定 义模 式下 的 SP ORR R1, R0, #UNDEFMODE MSR CPSR_c, R1 进入 未定 义模 式 LDR SP, =UnderfStack #设置 中止 模式 下的 SP ORR R1, R0, #ABORTMODE MSR CPSR_c, R1 进入 中止 模式 L
19、DR SP, =AbortStack #设置 IRQ 模 式下 的 SP ORR R1, R0, #IRQMODE MSR CPSR_c, R1 进入 IRQ 模式 LDR SP, =IRQStack #设置 FIQ 模式下 的 SP ORR R1, R0, #FIQMODE MSR CPSR_c, R1 进入 FIQ 模式 LDR SP, =FIQStack #设置 用户 模式 下的 SP ORR R1, R0, #USERMODE MSR CPSR_c, R1 进入 用户 模式 LDR SP, =UserStack stop: B stop .end ARM 嵌入式系统结构与 编程 第 2
20、 版, 邱铁 编著. 清华大学出版社. 2013 年 8 月第 2 版 ,2015 年 8 月第 4 次印 刷 5 内存数据区定义如下 : Src: .long 1,2,3,4,5,6,7,8,9,0xA,0xB,0xC,0xD,0xE,0xF,0x10 .long 1,2,3,4,5,6,7,8,9,0xA,0xB,0xC,0xD,0xE,0xF,0x10 Src_Num: .long 32 Dst: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 请用 ARM 指令编写程序 , 实现将数
21、据从源数据 区 Src 拷贝到目标数据区 Dst , 要求 以 6 个字为单位进 行块拷 贝, 如果不足 6 个字时则 以字为单位进行拷贝。 (其 中数据 区 Src_Num 处存放源数据 的个数) 解答:( 参考程序) /*- * 寄存器使用说 明: * R0: 源数据 区指 针 * R1: 目的数 据区 指针 * R2: 需要拷 贝的 字数 * R4-R9: 批量拷 贝使 用的 寄存 器组 *-*/ .global start .text start: LDR R0, =Src R0= 源 数据 区指 针 LDR R1, =Dst R1= 目 的数 据区 指针 LDR R2, =Src_N
22、um LDR R2, R2 获取 需要 拷贝 的字 数 CMP R2, #6 BCC copy_word 如果 R2 小于 6, 则进 行 字拷贝 copy_6word: LDMIA R0!, R4-R9 STMIA R1!, R4-R9 SUB R2, R2, #6 CMP R2, #6 BCS copy_6word 如果 R2 大于 6 则进 行 6 字块拷 copy_word: LDR R4, R0, #4 STR R4, R1, #4 SUBS R2, R2, #1 BNE copy_word ARM 嵌入式系统结构与 编程 第 2 版, 邱铁 编著. 清华大学出版社. 2013 年
23、8 月第 2 版 ,2015 年 8 月第 4 次印 刷 stop: B stop .ltorg Src: .long 1,2,3,4,5,6,7,8,9,0xA,0XB,0XC,0XD,0XE,0XF,0X10 .long 1,2,3,4,5,6,7,8,9,0xA,0XB,0XC,0XD,0XE,0XF,0X10 Src_Num: .long 32 Dst: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .end 6 将一个存放在R1 :R0 中的 64 位数据(其中 R1 中存放高
24、32 位)的高位和低 位对称换位,如第 0 位与 第 63 位调换,第 1 位与 第 62 位调换,第 2 位与 第 61 位调换,第 31 位与第 32 位调换。 解答:( 参考程序) /*- * 寄存器使用说 明: * R0: 源 数据 的低 32 位 * R1: 源 数据 的高 32 位 * R2: 目标数 据的 低 32 位 * R3: 目标数 据的 高 32 位 * R4: 计数器,初 值为 32, 递 减计 数至 0 * R5: 临时存 放数 据的 最低 位 *-*/ .global start .text start: LDR R0, =0X55555555 输 入数 据的 低
25、32 位 LDR R1, =0X55555555 输 入数 据的 高 32 位 MOV R2, #0 目 标数 据的 低 32 位 MOV R3, #0 目 标数 据的 高 32 位 MOV R4, #32 计 数器 shift_low: AND R5, R0, #1 取出源数据 低 32 位的最低位送 入 R5 中暂存 ORR R3, R5, R3, LSL #1 将 目标 数据 低 32 位 左 移一位,并将 取出的 数据 送到 其最 低位 MOV R0, R0, LSR #1 源 数据 低 32 位右 移一 位 ARM 嵌入式系统结构与 编程 第 2 版, 邱铁 编著. 清华大学出版社.
26、 2013 年 8 月第 2 版 ,2015 年 8 月第 4 次印 刷 SUBS R4, R4, #1 递 减计 数 BNE shift_low MOV R4, #32 恢 复计 数器 初值 shift_hight: AND R5, R1, #1 取 出源 数据 高 32 位的 最低位 送入 R5 中 暂存 ORR R2, R5, R2, LSL #1 将 目标 数据 高 32 位 左 移一位,并将 取出的 数据 送到 其最 低位 MOV R1, R1, LSR #1 源 数据 高 32 位右 移一 位 SUBS R4, R4, #1 递 减计 数 BNE shift_hight MOV R
27、0, R2 MOV R1, R3 stop: B stop .end 7 内存数据区定义如下 : DataZone DCD 0x12345678, 0x87654321, 0xABCDEF12, 0xCDEFAB45 DCD 0x20932197, 0xABC99DA3, 0x5522AB90, 0x338899A2 DCD 0x2345FDEA, 0x77AD3F61, 0x5290C316, 0x2728CE2A DCD 0x9AC67D4F, 0x8FB247AE, 0x2064887C, 0xCCB3267A DCD 0x2DFA1947, 0xA245861B, 0x9235AD78
28、, 0xC365A247 DCD 0x2F965AA4, 0x92348365, 0xABC90273, 0x47598334 DCD 0x453B346A, 0x23AE23DD, 0x35563242, 0x2354CAF2 DCD 0x54379652, 0xA354EF34, 0xBBB32523, 0x234B289A 以上可以看作 一个 8*4 矩 阵,请用 ARM 汇编语言 在 ARM 集成开发环境下 设 计程序,实现对矩阵 的转 置操作。 如果改为在 GNU ARM 环境下编程,程序应如 何修 改。 在 ARM 集成 开发 环境 下 编程: /*- * 寄存器使用说 明: *
29、R0: 存 放源 矩阵 数据 的起 始地址 * R1 : 指向 目标 知阵 数据 的 地址 * R2: 源矩阵 的行 坐标 * R3 : 源矩 阵的 列坐 标 * R4 : 转置 过程 中存 放临 时 数据 *-*/ AREA Conversion, CODE, READONLY ; 声明代 码段 Conversion ENTRY ; 标识程 序放 口 CODE32 start ARM 嵌入式系统结构与 编程 第 2 版, 邱铁 编著. 清华大学出版社. 2013 年 8 月第 2 版 ,2015 年 8 月第 4 次印 刷 LDR R0, =DataZone ; R0 为 源矩 阵的 数据
30、的起 始 地址 MOV R1, R0 ADD R1, R1, #128 ; R1 初 始化 为转 目标 矩阵 数 据的起 始地 址 MOV R2, #0 ; 行坐标 初始 为 0 MOV R3, #0 ; 列坐标 初始 为 0 col row ; 依 次 取 出 各 行 中 第 R3 列 的 数 据 MOV R4, R3 ADD R4, R4, R2, LSL #2 LDR R4, R0, R4, LSL #2 STR R4, R1, #4 ; 将取出 的数 存入 目标 矩 阵中 ADD R2, R2, #1 ; 行坐标 值 加 1, 准备 取下 一 行的数 据 CMP R2, #8 ; 判
31、断 是 否 已 经 取 到 最 后 一 行 BCC row ; 如果 R2 小于 8 则继 续循 环 MOV R2, #0 ; 行坐标 置 为 0, 回到 第一 行 ADD R3, R3, #1 ; 列坐标 值 加 1, 准备 处理 下 一行 CMP R3, #4 ; 判 断 是 否 已 经 处 理 到 最 后 一 BCC col ; 如果 R3 小于 4 则继 续循 环 stop B stop LTORG DataZone DCD 0x12345678, 0x87654321, 0xABCDEF12,0xCDEFAB45 DCD 0x20932197, 0xABC99DA3,0x5522AB
32、90, 0x338899A2 DCD 0x2345FDEA, 0x77AD3F61, 0x5290C316, 0x2728CE2A DCD 0x9AC67D4F, 0x8FB247AE, 0x2064887C, 0xCCB3267A DCD 0x2DFA1947, 0xA245861B, 0x9235AD78, 0xC365A247 DCD 0x2F965AA4, 0x92348365, 0xABC90273, 0x47598334 DCD 0x453B346A, 0x23AE23DD,0x35563242, 0x2354CAF2 DCD 0x54379652, 0xA354EF34, 0xB
33、BB32523, 0x234B289A END 在 GNU ARM 开发环境下编程: /*- ARM 嵌入式系统结构与 编程 第 2 版, 邱铁 编著. 清华大学出版社. 2013 年 8 月第 2 版 ,2015 年 8 月第 4 次印 刷 * 寄存器使用说 明: * R0: 存 放源 矩阵 数据 的起 始地址 * R1 : 指向 目标 知阵 数据 的 地址 * R2: 源矩阵 的行 坐标 * R3 : 源矩 阵的 列坐 标 * R4 : 转置 过程 中存 放临 时 数据 *-*/ .global start .text start: LDR R0, =DataZone R0 为源 矩阵 的
34、数据 的起 始地 址 MOV R1, R0 ADD R1, R1, #128 R1 初 始化 为转 目标矩 阵 数据的 起始 地址 MOV R2, #0 行 坐标 初始 为 0 MOV R3, #0 列 坐标 初始 为 0 col: row: 依 次取 出各 行中 第 R3 列的数 据 MOV R4, R3 ADD R4, R4, R2, LSL #2 LDR R4, R0, R4, LSL #2 STR R4, R1, #4 将 取出 的数 存入 目标 矩 阵中 ADD R2, R2, #1 行 坐标 值加 1 ,准 备取 下一行 的数 据 CMP R2, #8 判 断是 否已 经取 到最
35、后 一行 BCC row 如果 R2 小于 8 则继 续 循环 MOV R2, #0 行 坐标 置为 0 ,回 到第 一行 ADD R3, R3, #1 列 坐标 值加 1 ,准 备处 理下一 行 CMP R3, #4 判 断是 否已 经处 理到 最 后一 BCC col 如果 R3 小于 4 则继 续 循环 stop: B stop .ltorg DataZone: .int 0x12345678, 0x87654321, 0xABCDEF12,0xCDEFAB45 .int 0x20932197, 0xABC99DA3,0x5522AB90, 0x338899A2 .int 0x2345F
36、DEA, 0x77AD3F61, 0x5290C316, 0x2728CE2A .int 0x9AC67D4F, 0x8FB247AE, 0x2064887C, 0xCCB3267A .int 0x2DFA1947, 0xA245861B, 0x9235AD78, 0xC365A247 .int 0x2F965AA4, 0x92348365, 0xABC90273, 0x47598334 .int 0x453B346A, 0x23AE23DD,0x35563242, 0x2354CAF2 .int 0x54379652, 0xA354EF34, 0xBBB32523, 0x234B289A .
37、end ARM 嵌入式系统结构与 编程 第 2 版, 邱铁 编著. 清华大学出版社. 2013 年 8 月第 2 版 ,2015 年 8 月第 4 次印 刷 第 8 章 ARM 汇 编 语 言与 嵌入 式 C 混 合编 程 思 考与 练习 题 答案 1 严格按照嵌入式 C 语言的 编程规范, 写一个 C 语言 程序, 实现将一个二维 数 组 内的数据行和列进行 排序 。 解答: 对行和列分别 进行 排序: / 选择排序 void Sort(int* array, int count) int i,j,k,max; for (i=0;imax) max=arrayj; k=j; arrayk=a
38、rrayi; arrayi=max; / 直接作为 一维 数组 排序 void SortXY(int* array,int x,int y) Sort(array,x*y); Main() int array33=2,3,6,1,4,9,8,5,7; SortXY(int*)array,3,3); 2 嵌入式 C 程序设计中常用 的移位操作有哪几种, 请说 明每种运算所对应的 ARMARM 嵌入式系统结构与 编程 第 2 版, 邱铁 编著. 清华大学出版社. 2013 年 8 月第 2 版 ,2015 年 8 月第 4 次印 刷 指令实现。 解答: 右移, 对应LSR 3 volatile 限
39、制符在程序中起 到什么作用,请举例 说明 。 解答: volatile 的本意为 “ 暂态 的” 或.“ 易变的” , 该 说明 符起 到 抑 制编 译 器优 化 的作用 (此题 有这 句话 就算 对) 。 对于 一个 变量, 如果 编 译器发 现赋 值后 , 没 有变 化, 编 译器就 可能 优化 代码 ,直 接从内 部高 速缓 存 CACHE 或寄 存器 获取 数据 ,而 不是 从 内存中读取。如果在这段 时间里,变量被中断服务 或外围设备输入等编译器 未知的 原因更 改, 程序 可能 没有 获得最 新的 值而 导致 运行 结果异 常。 举例可 以参 考教 材 8.3.1 节 的实例 。
40、4 请分析下列程序代码 的执 行结果。 #include main() int value=0xFF1; int *p1,*p2,*p3, *p4; p1 = p2 = p3 = p4 = printf(“*p4=%xn“,*p4); 5 分析宏定义#define POWER(x) x*x 是否合理,举例 说明。如果不合理, 应如 何 更改? 解答: 不合理 , 如 果参 数 为 a+b ,则结 果 为a+b*a+b 错误 。 应改为 :#define POWER(x) (x)*(x) 6 条件 编译在程序设计 中有 哪些用途? 解答: 条件编 译的 功能 :只 对满 足某种 条件 的源 程序
41、 进行 编译。 可用来 提高 程序 的可 移植 性或是 输出 调试 信息 等。 ARM 嵌入式系统结构与 编程 第 2 版, 邱铁 编著. 清华大学出版社. 2013 年 8 月第 2 版 ,2015 年 8 月第 4 次印 刷 7 何为可重入函数?如 果使 程序具有可重入性, 在程 序设计中应注意哪些 问题 ? 解答: 如果某个 函数 可 以 被 多 个任 务 并 发 使用 , 而 不 会 造成 数 据错误 , 我 们 就说 这个 函数具 有可 重入 性, 相应 的这个 函数 就可 以称 为可 重入函 数 。 具体见 教 材 8.4 节的 说明 。 8 现有模块 module_1 ,modu
42、le_2 ,module_3 , 要求在模块 module_1 中提供可供 模块 module_2 ,module_3 使用的 int 型变量 xx ,请写出模块化程序设 计框 架。 解答 : 首先在 模 块 module_1 的.c 文件中 定 义 int xx = 0 然后在 模 块 module_1 的.h 文件中 声 明 int xx 为 外部 变量。 接下来 在模 块 module_2 源 文件中 包含 模 块 module_1 的.h 文件 : 在模 块 module_3 源 文件 中 包含模 块 module_1 的.h 文件 : 9 ATPCS 与AAPCS 的全 称是 什么
43、, 它 们有 什么 差别 ? 掌握子 程序 调用 过程 中寄 存器 的 使 用 规 则、 数 据 栈的 使用 规 则 及 参数 的 传 递规 则 , 在 具 体 的函 数 中 能够 熟练 应用 。 解答 : 见教 材8.5 节关 于ATPCS 与AAPCS 的 具体 说明 10 内嵌式汇编有哪些局 限性 ?编写一段代码采用 C 语 言嵌入汇编程序,在 汇 编程序中实现字符串 的拷 贝操作。 解答 :(1) 内嵌式汇编 的局限性见教材 8.6.1 节的具 体说明。 (2) 编写一段代码采用 C 语言嵌入汇编程序 , 在汇 编程序中实现字符串 的拷 贝操作, 参考程序如下: #include vo
44、id start() /*module_3.c*/ #include “ module_1.h“ /*module_2.c*/ #include “ module_1.h“ /*module_1.h*/ extern int xx ; /*module_1.c*/ int xx = 0; ARM 嵌入式系统结构与 编程 第 2 版, 邱铁 编著. 清华大学出版社. 2013 年 8 月第 2 版 ,2015 年 8 月第 4 次印 刷 char * a=“abcdefgh“; char * b=“; copy(a,b); / 通过调用 汇 编函数 , 将 两个 字符 串 R0 , R1 传到 内 嵌汇编 _asm ( “ copy:; LDRB R2,R0,#1; STRB R2,R1,#1; TST R2,#0XFF; BNE copy ; “ ); while(1);