您的当前位置:首页正文

ARM习题

来源:画鸵萌宠网
一、选择题(每小题2分,共20分)

1.下列操作系统不属于嵌入式操作系统的是:( A)。 (A)WinXP (B)uCOS (C)Linux (D)WinCE 2.ARM体系结构中3级流水结构的第2阶段是(B )。 (A)取指 (B)译码 (C)执行 (D) 编译 3.ARM一个字占( B)个字节。 (A)1 (B)4 (C)2 (D)8 4.作为堆栈指针寄存器的是(A)。 (A)R12 (B)R13 (C)R14 (D)R15 5.具有独立R8-15寄存器的工作模式是( D)。 (A)用户 (B)系统 (C)中断 (D)快中断 6.可以切换到Thumb状态的指令是:( A)。 (A)LDR R0,=LABLE+1 BX R0 (B)LDR R0,=LABLE BL R0 (C)LDR R0,=LABLE+1 BX R1 (D)LDR R0,LABLE+1 BL R0

7.FIQ和IRQ分别为禁止和允许时,CPSR中F和I的设置是:( A)。 (A)10 (B)01 (C)00 (D)11 8.IRQ中断返回指令是:(A)。 (A)MOVS PC,R14 (B)MOVS PC ,R14_SVC (C)SUBS PC,R14_IRQ,#4 (D)SUBS PC,R14_FIQ,#4 9.下列中断优先级最低的是:( D)。 (A)FIQ (B)IRQ (C)中止 (D)SWI

10.R1内容是4000H,4000H (4字节对齐)开始向上依次存放数据1,2,3,4,5,执

行指令LDMIA R1!,{R0,R1,R2,R3}后,R1中数据是:( A)。

(A)2 (B)3 (C)4 (D)

11.下列不属于ARM体系结构特点的是:( D)。 (A)大而统一的寄存器文件。 (B)数据的加载和存储结构。 (C)地址的自动增加和减少。 (D)不固定的指令长度。

12.ARM7TDMI中,T的含义是( A)。 (A)Thumb指令扩展 (B)支持片上调试 (C)硬件乘法指令 (D)观察点硬件 13.R0内容是1000H,执行STR R1,[R0,#4]!后,R0内容是(B)。 (A)1000H (B)1004H (C)1008H (D)100CH 14.作为链接寄存器的是(C)。 (A)R12 (B)R13 (C)R14 (D)R15 15.不属于异常模式的是(B)。 (A)管理 (B)系统 (C)中断 (D)快中断 16.可以切换到ARM状态的指令是:(B)。 (A)LDR R0,=LABLE+1 BX R0 (B)LDR R0,=LABLE BX R0 (C)LDR R0,=LABLE+1 BL R1 (D)LDR R0,LABLE+1 BL R0

1

17.FIQ和IRQ分别为允许和禁止时,CPSR中F和I的设置是:( B)。 (A)10 (B)01 (C)00 (D)11 18.FIQ中断返回指令是:(D)。 (A)MOVS PC,R14 (B)MOVS PC ,R14_SVC (C)SUBS PC,R14_IRQ,#4 (D)SUBS PC,R14_FIQ,#4 19.下列中断优先级最高的是:(B)。 (A)FIQ (B)未定义指令 (C)中止 (D)复位

20.R1内容是4000H,4000H (4字节对齐)开始向上依次存放数据1,2,3,4,5,执行指令LDMIB R1!,{R0,R1,R2,R3}后,R1中数据是:( B)。 (A)2 (B)3 (C)4 (D)5

二、基础知识填空题(每空2分,共20分) 1.ARM7两种处理器工作状态是( ARM )和( Thumb )。 2.程序状态寄存器是( CPSR),异常情况下程序状态寄存器是( SPSR )。 3.一个合理的8位位图是一个( 8 )位常数循环移位( 偶 )数位得到的。 4.基本指令后加(GT )表示本条语句有符号数大于时执行,加(NE )表示本条语句条件不相等时执行。 5.汇编程序入口伪指令是(ENTRY ),标明本段程序是代码段伪指令是( CODE )。 三、简答题(共14分)

1.ARM7TDMI体系寻址方式有哪几种?LDR R1,[R0,#0X08]属于哪种寻址方式?(5分) 答:有寄存器寻址、立即寻址、寄存器移位寻址、寄存器间接寻址、基址寻址、多寄存器寻址、堆栈寻址、块拷贝寻址和相对寻址。 LDR R1,[R0,#0X08]属于基址寻址 2.堆栈寻址方式有哪几种?(4分) 答:满递增; 满递减; 空递增; 空递减。

3.解释占先式内核含义?(5分)

答:在占先式内核中,最高优先级的任务一旦就绪,便能得到CPU的使用权。当一个运行着的任务使一个比它优先级高的任务进入就绪态时,当前任务被挂起,那个高优先级的任务立刻得到CPU的使用权开始运行。如果是中断服务子程序使一个高优先级的任务进入就绪态,则当中断完成时,被中断的任务被挂起,优先级高的任务开始运行。

第三章习题解答

1、ARM指令中的第二操作数“operand2”有哪些具体形式? 解:有三种:寄存器、寄存器移位、8位位图立即数。

2、 对于ARM的变址寻址方式,有基地址和偏移地址两部分组成。(1)基地址可以是哪些寄存器?(2)偏移地址可以有哪些形式?(3)总地址的计算方法有哪些?(4)变址寻址应用于哪些指令? 解:(1)基地址可以是通用寄存器R0---R15中的任意一个。 (2)偏移地址可以有三种形式:12位立即数、寄存器、寄存器移位。

2

(3)总地址的计算方法。有三种:前变址(前索引)、后变址(后索引)、自动变址。 (程序相对偏移)

– 前索引偏移:即先使用偏移传送数据;不定修改基地址。

如:LDR Rd,[Rn,#m]

– 后索引偏移:即先传送数据;后先使用偏移修改基地址。

如:LDR Rd,[Rn],#m

– 自动变址:即先使用偏移传送数据;再用偏移修改基地址。

如:LDR Rd,[Rn,#m ]! (4) 有4条指令: LDR、STR、LDM、STM

3、编写程序,将存储器从0x400000开始的200个字节的数据,传送到0x400800开始的区域。 解: MOV R0,#0x400000 LDR R1,=0x400800 MOV R7,#200 LP LDRB R2,[R0],#1 STRB R2,[R1],#1 SUBS R7, R7,#1 BNE LP HERE B HERE

4、 编写程序,比较存储器中0x400000和0x400004两无符号字数据的大小,并且将比较结果存于0x400008的字中,若两数相等其结果记为0,若前者大于后者其结果记为1,若前者小于后者其结果记为-1。 解: MOV R0,#0x400000 LDR R1,[R0] ;取第1个数 LDR R2,[R0,#4] ;取第2个数 CMP R1,R2 ;两个数相比较 MOVHI R1,#1 ;R1大 MOVLO R1,# -1 ;R1小 MOVEQ R1,#0 ;两个数相等 STR R1,[R0,#8]

5、 存储器从0x400000开始的100个单元中存放着ASCII码,编写程序,将其所有的小写字母转换成大写字母,对其它的ASCII码不做变换。 解: MOV R0,#0x400000 MOV R1,#0 LP LDRB R2,[R0,R1] CMP R2,#0x61 BLO NEXT CMP R2,#0x7B ;0x7A为z SUBLO R2, R2,#0x20

3

STRBLO R2,[R0,R1] NEXT ADD R1, R1,#1 CMP R1,#100 BNE LP

6、编写一程序,查找存储器从0x400000开始的100个字中为0的数目,将其结果存到0x400190中。 解: MOV R0,#0x400000 MOV R1,#0 MOV R7,#100 LP LDR R2,[R0],#4 CMP R2,#0 BNE NEXT ADD R1,R1,#1 NEXT SUBS R7,R7,#1 BNE LP STR R1,[R0] B $

7、 编写一程序,存储器中从0x400200开始有一个64位数。(1)将取反,再存回原处;(2)求其补码,存放到0x400208处 。 解: LDR R0,=0x400200 LDR R2,=0xFFFFFFFF LDR R1,[R0] ;取低32位数 EOR R1,R1,R2 ;取反 STR R1,[R0] ;存低32位反码 ADDS R1,R1,#1 ;又加1为求补 STR R1,[R0,#8] ;存低32位补码 LDR R1,[R0,#4] ;取高32位数 EOR R1,R1,R2 ;取反 STR R1,[R0,#4] ;存高32位反码 ADC R1,R1,#0 ;高32位求补 STR R1,[R0,#12] ;存高32位补码

8、 编写一简单ARM汇编程序段,实现1+2+…+100的运算。 解: MOV R2,#100 MOV R1,#0 LOOP

4

ADD SUBS BNE B R1,R1,R2 R2,R2,#1 LOOP $

;R1中为累加和 ;R2控制循环

第四章程序题解答

11、编写一程序,用查询的方式,对S3C2410X的A/D转换器的第0通道连续进行100次A/D转换,然后将其结果求平均值。注意:A/D转换器有独立的模拟信号输入引脚AIN0---AIN9。

ADCCON=(1<<14)|(pref<<6)|(ch<<3)|1; //允许预分频,启动转换

#define rADCCON (*(volatile unsigned *)0x58000000) #define rADCDAT0 (*(volatile unsigned *)0x5800000c) #define pref 49 #define ch 0 int adc(void) { rADCCON=(1<<14)|(pref<<6)|(ch<<3)|1; //允许预分频,启动转换 while(rADCCON&0x01==1); //查询是否已经启动转换 while(rADCCON&0x8000==0); //查询转换是否结束 return rADCDAT0&0x3ff; //读取转换结果 }

void main() { int adc_data=0, i; for(i=0;i<100;i++) adc_data+=adc(); adc_data=adc_data/100; printf(\"adc average is: %d\\n\",adc_data); }

14、编写一程序,使用外部中断EINT0,用中断方式对端口C做数据输入。(注意对中断系统和相关引脚进行初始化)

#define BIT_ALLMSK (0xffffffff) #define BIT_EINT0 (0x01) #define rGPCCON (*(volatile unsigned *)0x56000020) #define rGPCDAT (*(volatile unsigned *)0x56000024) #define rGPFCON (*(volatile unsigned *)0x56000050)

5

#define rEXTINT0 (*(volatile unsigned *)0x56000088) #define rSRCPND (*(volatile unsigned *)0x4A000000) #define rINTMSK (*(volatile unsigned *)0x4A000008) #define rINTPND (*(volatile unsigned *)0x4A000010) pISR_EXINT0 EQU (ISR_STARTADDRESS+0x20) int gpc_data;

static void __irq Eint0Int(void) {

rSRCPNG = (BIT_EINT0); //清除中断请求标志 rINTPNG = (BIT_EINT0); //清除中断服务标志 gpc_data= rGPCDAT; //读取端口C的输入值 }

void main(void) {

int tmp=-1;

rGPFCON=rGPFCON&~(0x03)|0x02; //GPF0设置为外中断0请求输入 rGPCCON=rGPCCON&(0x00); //全部输入 rGPEXINT0=rGPEXINT0&~(0x07)|0x03; //下降沿触发 rINTMKS =~(BIT_EINT0); //开中断屏蔽 pISR_EXINT0=(U32)Eint0Int; //设置中断向量 while(1) { if(tmp!=gpc_data) { tmp=gpc_data; printf(\"gpc_data=%d\\n\"); } } }

16、编写一程序,使用timer0产生并输出频率为10KHz、占空比为1/2的方波。设f pclk=50MHz。(注意对timer0和相关引脚初始化)

总分频数值=50M/10K=5000

设预分频为25(预分频值为25-1=24),分频为2,计数器初值应该为100,这样总分频数值=25*2*100=5000 所以:计数初值为100,比较寄存器值为100/2=50 TCFG0=24 TCFG1=TCFG1 & 0 | (0<<20) | (0<<0) TCON=TCON & ~(0x0F) | 0x0a TCON=TCON & ~(0x0f) | 0x09

6

程序如下:

#define rGPBCON (*(volatile unsigned *)0x56000010) #define rTCFG0 (*(volatile unsigned *)0x51000000) #define rTCFG1 (*(volatile unsigned *)0x51000004) #define rTCON (*(volatile unsigned *)0x51000008) #define rTCNTB0 (*(volatile unsigned *)0x5100000C) #define rTCMPB0 (*(volatile unsigned *)0x51000010)

void main(void) { rGPBCON=rGPBCON & ~0x03 | 0x02; //设置T0输出引脚 rTCFG0=24; //设置预分频 rTCFG1=0; //设置T0(中断/DMA)模式和分频 rTCNTB0=100; //设置T0初值 rTCMPB0=50; //设置T0比较值 rTCON=rTCON & ~0x0f | 0x0a; //设置控制寄存器,手动装载T0初值 rTCON=rTCON & ~0x0f | 0x09; //设置控制寄存器,自动重装、启动运行 while(1); }

19、编写一程序,使用S3C2410的UART2进行串行数据收发(假设接收、发送均是200字节),要求用脉冲请求中断的方式、使用收/发FIFO,8个数据位、1个停止位、不校验,波特率为125kb/s。设Pclk为50MHz。(提示:主程序对UART2初始化、引脚配置、中断初始化等,并进行一次发送;中断服务程序进行收发,并且清除中断请求标志和中断服务标志)

#define rGPHCON (*(volatile unsigned *)0x56000070) #define rULCON2 (*(volatile unsigned *)0x50008000) #define rUCON2 (*(volatile unsigned *)0x50008004) #define rUFCON2 (*(volatile unsigned *)0x50008008) #define rUTRSTAT2 (*(volatile unsigned *)0x50008010) #define rUTxH2 (*(volatile unsigned *)0x50008020) #define rURxH2 (*(volatile unsigned *)0x50008024) #define rUBRDIV2 (*(volatile unsigned *)0x50008028) #define pclk 50000000 #define BAUDRATE 125000

#define BIT_ALL (0xffffffff) #define BIT_UART2 (0x8000) #define BIT_RXD2 (0x40) #define BIT_TXD2 (0x80) #define rSRCPND (*(volatile unsigned *)0x4A000000)

7

#define rINTMSK (*(volatile unsigned *)0x4A000008) #define rINTPND (*(volatile unsigned *)0x4A000010) #define rSUBSRCPND (*(volatile unsigned *)0x4A000018) #define rSUBINTMSK (*(volatile unsigned *)0x4A00001C) pISR_UART2 EQU (ISR_STARTADDRESS+0x5C)

static char rxd_data[200], txd_data[200]; static char rxd_num=0, txd_num=0;

void read_rxd(void) { char i; for(i=0; i<8; i++,rxd_num++) { if(rxd_num>199) break;

rxd_data[rxd_num]= rURxH2& 0xff;

} }

void write_txd(void) { char i; for(i=0; i<8; i++,txd_num++) { if(txd_num>199) break;

rUTxH2 = txd_data[txd_num];

} }

static void __irq Uart2Int(void) {

rSRCPNG = (BIT_UART2); //清除中断请求标志rINTPNG = (BIT_UART2); //清除中断服务标志if(Rsubsrcpnd & BIT_RXD2) //判断是哪种子中断{ rSUBSRCPND= BIT_RXD2; //是接收子中断 read_rxd2(); //读取数据 }

Else if(Rsubsrcpnd & BIT_TXD2) { rSUBSRCPND= BIT_TXD2; //是发送子中断 write_txd2(); //发送数据 } }

void main() { rGPHCON= rGPHCON ~ (0xf<<12) | (0xa<<12)

8

//定义GPH6、GPH7分别为串行口2的接收和发送

rULCON2=0x03; //设置数据帧格式 rUCON2 = 0b000 0100 0101=0x045; //设置控制寄存器 rUFCON2 = 0b1001 0001 = 0x91; //发送接收FIFO都是8字节触发中rUBRDIV2=( (int)(pclk/16./BAUDRATE) -1 );

//设pclk为50MHz,波特率除数为24

rINTMKS =~(BIT_RART2); //开中断屏蔽 pISR_UART2=(U32)Uart2Int; //设置中断向量 write_txd2(); //发送8字节 write_txd2(); //再发送8字节 rSUBINTMSK = rSUBINTMSK ~((BIT_TXD2) | (BIT_RXD2)); //开子中断屏蔽 while(rxd_num<200&&txd_num<200); if(rxd_num<200) while(rxd_num<200); else while(txd_num<200);

rSUBINTMSK = rSUBINTMSK | (BIT_TXD2) | (BIT_RXD2); //屏蔽子中断 rINTMKS = rINTMKS | (BIT_UART2); //屏蔽UART2中断 }

25、编写一程序,对S3C2410的RTC进行设置,使用报警功能,每1小时报警中断一次,中断后显示出当前的日期和时间。初始日期、时间要设置为正确值。

#define rRTCCON (*(volatile unsigned char *)0x57000043) //RTC control

#define rRTCALM (*(volatile unsigned char *)0x57000053) //RTC alarm control #define rALMSEC (*(volatile unsigned char *)0x57000057) //Alarm second #define rALMMIN (*(volatile unsigned char *)0x5700005b) //Alarm minute #define rALMHOUR (*(volatile unsigned char *)0x5700005f) //Alarm Hour #define rBCDSEC (*(volatile unsigned char *)0x57000073) //BCD second #define rBCDMIN (*(volatile unsigned char *)0x57000077) //BCD minute #define rBCDHOUR (*(volatile unsigned char *)0x5700007b) //BCD hour #define rBCDDATE (*(volatile unsigned char *)0x5700007f) //BCD day #define rBCDDAY (*(volatile unsigned char *)0x57000083) //BCD date #define rBCDMON (*(volatile unsigned char *)0x57000087) //BCD month #define rBCDYEAR (*(volatile unsigned char *)0x5700008b) //BCD year

#define rSRCPND (*(volatile unsigned *)0x4a000000) //Interrupt request statusl #define rINTMSK (*(volatile unsigned *)0x4a000008) //Interrupt mask control #define rINTPND (*(volatile unsigned *)0x4a000010) //Interrupt request status //************************[ Rtc_Init ]*********************************

9

void main(void) {

rRTCCON = 0x1; //No reset, Merge BCD counters, 1/32768, RTC Control enable //设置当前日期时间 rBCDYEAR = 0x07; rBCDMON = 0x11 ;

rBCDDATE = 0x18;

rBCDDAY = 0x07; //SUN:1 MON:2 TUE:3 WED:4 THU:5 FRI:6 SAT:7 rBCDHOUR = 0x09; rBCDMIN = 0x25; rBCDSEC = 0x00; //设置报警 rALMMIN = 0; //只要分钟、秒同时为0就报警,即整小时报警

rALMSEC = 0;

rRTCALM = 0x43; //Global, Minute,Second alarm enable

rRTCCON = 0x0; //No reset, Merge BCD counters, 1/32768, RTC Control disable

pISR_RTC = (unsigned int)Rtc_Int; //设置中断向量 rINTMSK = ~(BIT_RTC); //开RTC中断 }

//----------------------------------------------------------------------- void __irq Rtc_Int(void) {

int year,month,date, hour,minn,sec;

rSRCPND = BIT_RTC; rINTPND = BIT_RTC; //读取读取的日期和时间

year = 0x2000 + rBCDYEAR; month = rBCDMON; date = rBCDDATE; hour = rBCDHOUR; minn = rBCDMIN; sec = rBCDSEC;

Uart_Printf(\"%2x : %2x : %2x, %2x/%2x/%4x\\n\ }

10

因篇幅问题不能全部显示,请点此查看更多更全内容

Top