ARM嵌入式系统结构与编程习题答案 清华大学出版社 最详细版 下载本文

16

(2)申请以Str_buffer为起始地址的连续的内存单元,并用字符串“ARM7 and ARM9”进行初始化;

答:(1) data_buffer1 DCW 0x11,0x22,0x33,0x44,0x55 (2) Str_buffer DCB “ARM7 and ARM9”

6.定义一个结构化的内存表,其首地址固定为0x900,该结构化内存表包含2个域,Fdatal长度为8个字节,Fdata2长度为160个字节。 答:MAP 0x900

Fdata1 FIELD 8 Fdata2 FIELD 160

7.在GNU-ARM编译环境下,写出实现下列操作的伪操作:

(1)分配一段字节内存单元,并用57,0x11,031,'Z',0x76进行初始化; (2)分配一段半字内存单元,并用0xFFE0,0xAABB,0x12进行初始化; (3)分配一段字内存单元, 并用0x12345678,0xAABBCCDD进行初始化; (4)分配一段内存单元,并用长为8字节的数值0x11填充100次; 答:

(1)分配一段字节内存单元,并用57,0x11,031,'Z',0x76进行初始化; .byte 57,0x11,031,'Z',0x76

(2)分配一段半字内存单元,并用0xFFE0,0xAABB,0x12进行初始化; .hword 0xFFE0,0xAABB,0x12

(3)分配一段字内存单元, 并用0x12345678,0xAABBCCDD进行初始化; .word 0x12345678,0xAABBCCDD

(4)分配一段内存单元,并用长为8字节的数值0x11填充100次; .fill 100 , 8, 0x11

8.写出与GNU-ARM编译环境下伪操作.arm , .thumb 功能相同的ARM标准开发工具编译环境下的伪操作。

答:.arm 对应 ARM 或 CODE32 .thumb 对应 THUMB 或 CODE16

第7章 汇编语言程序设计

1.分别写出ARM集成开发环境下ARM汇编语句格式与GNU ARM环境下ARM汇编语句通用格式,并分析它们的区别。

答:ADS环境下ARM汇编语句格式如下:

? {symbol} {instruction} {;comment} ? {symbol} {directive} {;comment} ? {symbol} { pseudo-instruction} {;comment}

? Symbol :标号(地址)

? Instruction :指令(ARM/Thumb) ? Directive :伪操作 ? pseudo-instruction:伪指令

GNU环境下ARM汇编语言语句格式如下:

16

17

? {label :} {instruction} ? {label :} {directive} ? {label :} { pseudo-instruction} {@comment} {@comment} {@comment}

2.局部标号提供分支指令在汇编程序的局部范围内跳转,它的主要用途是什么,并举一实例加以说明。 答:局部标号

? 局部标号的语法格式如下:

? n {routname} (0~99) ? 被引用的局部标号语法规则是: ? % {F∣B} {A∣T} n {routname} ? 其中:

? n是局部标号的数字号。(0~99) ? routname是当前局部范围的名称。 ? %表示引用操作。

? F指示汇编器只向前搜索。 ? B指示汇编器只向后搜索。

? A指示汇编器搜索宏的所有嵌套层次。 ? T指示汇编器搜索宏的当前层次。

? 局部标号提供分支指令在汇编程序在局部范围内的跳转

3.先对内存地址0xB000开始的100个字内存单元填入0x10000001~0x10000064字数据,然后将每个字单元进行64位累加,结果保存于【R9:R8】(R9中存放高32位)。

答:解:先对内存地址0xB000开始的100个字内存单元填入0x10000001~0x10000064字数据,然后将每个字单元进行64位累加,结果保存于【R9:R8】(R9中存放高32位)。

在ARM集成开发环境下编程:

/*---------------------------------------------------------------------------------------- ********寄存器使用说明************************ ***R0:存放地址值 ***R2:递减计数器

***R9:64位递加结果的高32位 ***R8:64位递加结果的低32位

*---------------------------------------------------------------------------------------------*/ AREA Fctrl,CODE,READONLY ;声明代码段Fctrl ENTRY ;标识程序入口 CODE32 ;声明32位ARM指令 START MOV R0,#0xB000 ;初始化寄存器 MOV R1,#0x10000001 MOV R2,#100 loop_1 ;第一次循环赋值 STR R1,[R0],#4 ADD R1,R1,#1

17

18

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 ;R8=R8+R1,进位影响标志位 ADDC R9,R9,#0 ;R9=R9+C,C为进位位 SUBS R2,R2,#1 BNE loop_2 Stop B Stop ;文件结束 END

4.在GNU环境下用ARM汇编语言编写程序,初始化ARM处理器各模式下的堆栈指针SP_mode (R13),各模式的堆栈指针地址如下:

.equ _ISR_STARTADDRESS, 0xCFFF000 @设置栈的内存基地址 .equ UserStack, _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模式堆栈地址 答:

在GNU ARM开发环境下编程:

.equ _ISR_STARTADDRESS, 0xCFFF000 @设置栈的内存基地址 .equ UserStack, _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 USERMODE 0x10 @用户模式 .equ FIQMODE 0x11 @FIQ模式 .equ IRQMODE 0x12 @IRQ模式 .equ SVCMODE 0x13 @管理模式 .equ ABORTMODE 0x17 @中止模式 .equ UNDEFMODE 0x1B @未定义模式 .equ SYSMODE 0x1F @系统模式 .equ MODEMASK 0x1F @模式位掩码控制字

18

19

.global _start .text .arm _start: MRS R0,CPSR @读取当前CPSR BIC R0,R0,#MODEMASK @清除模式位 @设置系统模式下的SP ORR R1,R0,#SYSMODE MSR CPSR_c,R1 LDR SP,=UserStack @设置中止模式下的SP ORR R1,R0,#ABORTMODE MSR CPSR_c,R1 LDR SP,=AbortStack @设置管理模式下的SP ORR R1,R0,#SVCMODE MSR CPSR_c,R1 LDR SP,=SVCStack @设置IRQ模式下的SP ORR R1,R0,#IRQMODE MSR CPSR_c,R1 LDR SP,=IRQStack @设置FIQ模式下的SP ORR R1,R0,#FIQMODE MSR CPSR_c,R1 LDR SP,=FIQStack

Stop : B Stop .end @文件结束

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

19

20

.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

请用ARM指令编写程序,实现将数据从源数据区Src拷贝到目标数据区Dst,要求以6个字为单位进行块拷贝,如果不足6个字时,则以字为单位进行拷贝(其中数据区Src_Num处存放源数据的个数)。

答:解:程序设计思路:每进行6个字的批量拷贝前,先判断SRC_NUM是否大于6,是则进行6字的批量拷贝并将SRC_NUM减去6,否则则进行单字的拷贝,在使用寄存器组时还要注意保存现场。

在ARM集成开发环境下编程:

/*---------------------------------------------------------------------------------------- ********寄存器使用说明************************ ***R0:源数据区指针 ***R1:目标数据区指针 ***R2:单字拷贝字数 ***R3:块拷贝字数

***R5~~R10:批量拷贝使用的寄存器组 ***SP:栈指针

*---------------------------------------------------------------------------------------------*/ SRC_NUM EQU 32 ;设置要拷贝的字数 AREA Copy_Data,CODE,READONLY ;声明代码段Copy_Data ENTRY ;标识程序入口 CODE32 ;声明32位ARM指令 START LDR R0,=Src ;R0=源数据区指针 LDR R1,=Dst ;R1=目标数据区指针 MOV R2,#SRC_NUM ;R2=单字拷贝字数 MOV SP,#0x9000

CMP R2,#6

BLS Copy_Words ;R2<=6,则拷贝单字 STMFD SP!,{R5-R10} ;保存将要使用的寄存器组R5-R10 ;进行块拷贝,每次拷贝6个字 Copy_6Word LDMIA R0!,{R5-R10} STMIA R1!,{R5-R10} SUBS R2,R2,#6 BHI Copy_6Word ;R2>6 LDMFD SP!,{R5-R10} ;恢复寄存器组R5-R10

;将剩余的数据区以字为单位拷贝 Copy_Words ;拷贝剩余字节 LDR R3,[R0],#4 STR R3,[R1],#4 SUBS R2,R2,#1 BNE Copy_Word

20