当前位置:文档之家› 读书笔记----ARM汇编 编程

读书笔记----ARM汇编 编程

读书笔记----ARM汇编 编程
读书笔记----ARM汇编 编程

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59/********************************************************************************* ****************************************文件头************************************ ** 《ARM体系结构与编程》读书笔记 ** ** 成功的步伐在您不懈的努力中加快! ** **源自: METAL MAX, CUIT **起始日期:01/25/08 **当前版本:Version0.08.0125 ** **备注: 1.这是2008春节回家期间阅读《ARM体系结构与编程》这部作品的时候记载下来的。 小小的东西凝聚了我不少的心血(汗...书又不是我写的,我只是负责抄写了一遍, 有些内容给省略了...),让我体会到要真真正正做个像样的东西很不容易,但是, 相信点点滴滴的积累,正所谓是:不积跬步,无以至千里;不积小流,无以成江海! 2.由于刚接触ARM处理器,并不熟悉其中的一些细节问题,所有在做笔记的时候对有 西理解不是很透彻,甚至会又错误。有些地方加入了自己的一些东西(主要是一些 的理解和自己做的图表)。

3.由于本人水平太菜的缘故,排版不工整,存在错别字等问题,见谅!更希望有心人 忙修改和完善,众志成城!

4.本文档您可以任意的修改(严禁恶搞!^_^)和传播,引用文档的部分和全部内容请 本文件的文件头,如果您是有心人修改或完善了其中的部分内容,请一定保留您的 改记录(修改日期、版本、修改人以及修改点等),并将其归入文件头中。

5.编辑时使用了三号新宋体字体以及演示版的Editplus2,TABLE缩进为4,制表符代 空格。

6.非常喜欢我的事业,也很希望能和大家一起学习很进步,当然交流是前提!

Email : liyangbbs@https://www.doczj.com/doc/e814277908.html,

QQ: 249456711

日志: 01/25/08 - 02/10/08 Version0.08.0125 METL MAX

********************************************************************************** 2008-1-25

一、前言:

嵌入式系统: 是指以应用为中心,以计算机技术为基础,软件和硬件可以裁剪,

适应应用系统对功能的、可靠性、体积和功耗严格要求的专用计算 机系统。

ARM: ACRON RISC COMPUTER <---> ADVANCED RISC COMPUTER

ARM技术的发展历程:第一片ARM处理器是在1983年10月到1985年4月位于英国剑桥的

ACRON COMPUTER公司开发的。于1985年4月26日在ACRON公司进 行了首批ARM样片测试并成功运行了测试程序。

1990年11月ARM公司在英国剑桥的一个谷仓里成立最初只有12人。

第一章、ARM体系的结构和特征。

CHAP1.1

AMR芯片具有RISC体系的一般特点,如:

1.具有大量的寄存器。

2.绝大部分的操作就在寄存器中进行,通过LOAD,STORE的体系结构在内存和寄存

器之间传递数据。

61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119

4.采用固定长度的指令格式。

AMR芯片具有的一些特别的技术:

1.在同一条数据处理指令中包含 算术逻辑处理单元 和 移位处理。

2.使用地址自动增加(减少)来优化程序中循环处理。

3.LOAD/STORE指令可以批量传输数据,从而提高数据传输的效率。

4.所有指令都可以根据前面指令的执行结果,决定是否执行,以提高指令的执行

效率。

CHAP1.2

AMR体系结构的版本和命名方法。

迄今为止,ARM体系结构共定义了6个版本,版本号分别为1-6。

CHAP1.2.1ARM体系的结构版本:

1.版本1 : V1体系

*处理乘法指令以外的基本数据处理指令。

*基于字节、字和多字的LOAD/STORE指令。

*包括子程序BL在内的跳转指令。

*共操作系统使用的软件中断指令:SWI。

*本版本总地址空间是26位,目前已经不在使用。(2^26 = 64MB) 2.版本2 : V2体系

*乘法指令和乘加指令。

*支持协处理器的指令。

*对于FIQ模式,提供额外的两个备份寄存器。

*SWP指令及SWPB指令。

*本版本总地址空间是26位,目前已经不在使用。

3.版本3 : V3体系

*地址扩展到32位,除去3G版本以外的其他版本是向前兼容的, 支持26位地址空间。

*程序状态寄存器从原来的R15移动到新的专用寄存器:

Current Program Status Register

*增加了SPSR用于异常中断程序时,保存被中断程序的状态。

Saved Program Status Register

*增加了两种处理器模式,是操作系统代码可以方便地使用数据访问 中止异常、指令预取异常和未定义指令异常。

*增加了MSR,MRS。用于访问CPSR,SPSR寄存器。

*修改了原来版本中的从异常返回的指令。

4.版本4 : V4体系

*半字的读取和写入指令。

*读取(LOAD)带符号的字节和半字数据的指令。

*增加了T变种,可以使处理器切换到Thumb状态。

*增加了处理器的特权模式。在该模式下使用的是用户模式下的寄存器。

*版本4中明确定义了哪些指令会引起未定义指令异常。版本4不再强制

要求于以前的26位地址空间兼容。

5.版本5 : V5体系

*提高了T变种中ARM/THUMB混合使用的效率。

*对T变种的指令和非T变种的指令使用相同的代码生成技术。

*增加了前导零计数(COUNT LEADING ZEROS)指令,该指令可以使整数除法

和中断优先级排队操作的更为有效。

*增加了软件断点指令。

*为协处理器提供了更多的可选择的指令。

*更加严格的定义了乘法指令堆条件标志位的影响。

6.版本6 : V6体系

*2001年发布,其主要特点是增加了SIMD功能扩展。它适合永电池供电 的高性能便携式设备。

CHAP1.2.2 ARM体系的变种:

1.T(THUMB)。

2.M(长乘法指令)。

121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179

4.J(JAVA加速器JAZELLE)。

5.SIMD(ARM多媒体扩展)。

CHAP1.2.3 ARM/THUMB体系版本的命名格式

表示AMR/THUMB体系版本的字符串是由下面几个部分组成的: ARM v5 T exP

┃ ┃ ┃ ┃

┃ ┃ ┃ ┖要排除的功能

┃ ┃ ┖变种名称

┃ ┖版本号

┖ARM字符串

1.ARM字符串。

2.ARM版本号。

3.X表示排除某种功能。

2008-1-26

CHAP1.3 ARM处理器系列

1.ARM7:

ARM7TDMI,ARM7TDMI-S,ARM7EJ-S,ARM720T-4

AMR7 T D M I - S

┃ ┃┃┃┃ ┃

┃ ┃┃┃┃ ┖可综合(SYNTHESIZABLE)版本软核

┃ ┃┃┃┖EmbededICE硬件调试仿真功能

┃ ┃┃┖64位乘法指

┃ ┃┖片上调试

┃ ┖THUMB指令

┖AMR7

2.ARM9:

ARM9系列处理器使用了ARM9TDMI内核,其中包含了16位的THUMB指令集。

3.ARM9E:

ARM9E系列处理器使用单一的处理器内核提供了微控制器、DSP、JAVA应用 系统的解决方案,从而极大的减小了芯片的大小及复杂程度,降低了功耗 缩短了产品面世的时间。

4.ARM10E:

ARM10E系列处理器有高性能和低功耗的特点。其采用了新的节能模式,提 供了64位的读取和写入体系,包含向量操作的满足IEEE754的浮点运算协处 理器,系统集成更加方便,拥有完整的硬件和软件可开发工具。

包含:ARM1020E,ARM1022E,ARM1026EJ-S

5.SECURCORE:

提供了基于高性能的32位RISC技术的安全解决方案。

包含:SECURCORE SC100, SECURCORE SC110, SECURCORE SC200,

SECURCORE SC210。

CHAP1.4 ARM处理器模式

7种运行模式:

https://www.doczj.com/doc/e814277908.html,R(USER).

2.FIQ(FAST INTERRUPT RQUEST)

3.IRQ(INTERRUPUT RQUEST)

4.SVE(SUPERVISOR)

5.ABT(ABORT)

6.UND(UNDEFINED)

181

182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239CHAP1.5 ARM寄存器介绍

37个寄存器:

第一类:31个通用寄存器,包括PC在内。都是32位的。

第二类:6个状态寄存器,都是32位的目前只使用了一部分的位。

┏━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ user ┃ Privileged Mode ┃ ┃ mode ┣━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┫ ┃ ┃system ┃ excepution ┃ ┣━━━━╋━━━━╋━━━━┳━━━━┳━━━━┳━━━━┳━━━━┫ ┃ usr ┃ sys ┃ svc ┃ abt ┃ und ┃ irq ┃ fiq ┃ ┣━━━━┻━━━━┻━━━━┻━━━━┻━━━━┻━━━━┻━━━━┫ ┃ R0 <----> R7 ┃ ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━┫ ┃ R8 <----> R12 ┃R8_fiq ┃ ┣━━━━━━━━━┳━━━━┳━━━━┳━━━━┳━━━━╋━━━━┫ ┃ R13 ┃R13_svc ┃R13_abt ┃R13_und ┃R13_irq ┃R13_fiq ┃ ┣━━━━━━━━━╋━━━━╋━━━━╋━━━━╋━━━━╋━━━━┫ ┃ R14 ┃R14_svc ┃R14_abt ┃R14_und ┃R14_irq ┃R14_fiq ┃ ┣━━━━━━━━━┻━━━━┻━━━━┻━━━━┻━━━━┻━━━━┫ ┃ PC ┃ ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫

┃ CPSR ┃

┣━━━━━━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┫

┃ ┃SPSR_svc┃SPSR_abt┃SPSR_und┃SPSR_irq┃SPSR_fiq┃

┗━━━━━━━━━┻━━━━┻━━━━┻━━━━┻━━━━┻━━━━┛

寄存器的讲解:

R0 - R7 : 未备份寄存器。通过上表可以看出,这几个寄存器在不同模式下使用的 都是同样的物理寄存器。所以对它们进行操作时都要注意备份保存。

R13 : 这个寄存器一般用来做堆栈的指针。个种异常模式都拥有自己的堆栈

指针,所以在进行处理器初始化的时候要对每种模式的堆栈区域进行。

R14(LR) : 顾名思义,连接寄存器。用来保护程序返回地址。

可以通过下面的两种方式来实现子程序的返回:

1.MOV PC, LR

2.BX LR(注意:BX指令会根据PC最后一位来确定是否要进入THUMB)

R15(PC) : 1.由于ARM处理器采用了流水线机制。当前的PC值和当前执行的指令有 一定的偏移。在ARM7中,3级流水,PC+8。

2.注意:由于具体的芯片的不同,在使用STM/STR保存R15的时候,有可能

保存的是当前的PC+8,也有肯保存的是PC+12.对于同一的芯片这个是个

常量,但是如果要进行程序移植就有可能带来错误,所以要么避免使用

STM/STR来保存R15,要么测量出到底是PC+8,还是PC+12,或者其他。

测试的程序:

SUB R1, PC, #4;获取STR指令的地址。

PC-4-->STR PC, [R0] ;保存PC + X的值,也就是把偏移值读出来。

PC---> LDR R0, [R0] ;保存偏移值到R0中

PC+4-->SUB R0, R0, R1;求出偏移值。

PC+8-->XXX X, X, X

PC+12->XXX X, X, X

3.当成功的向R15中写入值,则程序将跳转到该地址继续执行。由于AR

指令是字对齐的,所以地址的最后两位应该为0.同理THUMB状态下指令

是以半字对齐的,所以最后一位应该为0.

4.BX指令对R15的要求。BX指令测试R15的最后一位来决定是否进入到T

241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 5.MOV PC, PC 这种读取PC和写入PC不对称的指令要特别注意,由于流

的影响。

CPSR :

┏━┳━┳━┳━┳━┳━//━━┳━┳━┳━┳━┳━┳━┳━┳━┓ ┃N ┃Z ┃C ┃V ┃Q ┃RESERVED┃I ┃F ┃T ┃M4┃M3┃M2┃M1┃M0 ┗┳┻┳┻┳┻┳┻┳┻━//━━┻┳┻┳┻┳┻┳┻┳┻┳┻┳┻┳┛ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ 保留 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗v5E系列DSP ┃ ┃ ┃ ┗━┻━╋━┻━┛ ┃ ┃ ┃ ┗溢出 ┃ ┃ ┃ 处理器模式

┃ ┗零 ┃ ┗快速中断

┗负 ┗中断

负零进溢,中快状模。

1. 以下指令会影响CPSR中的【标志位】:

*比较指令:CMP,CMN,TEQ,TST。

*当一些算术指令和逻辑指令的目标寄存器不是R15时,这些指令会影响CPSR

中的条件标志位。

*MSR指令可以向CPSR写入新的值。

*MRC指令将R15作为目标寄存器时,可以吧协处理器产生的条件标志位的 传送到ARM处理器。

*一些LDM指令的变种指令可以将SPSR的值复制到CPSR中,这种操作主要用 从异常中断程序中返回。

*一些带‘位设置’的算术和逻辑指令的变种指令,也可以将SPSR的值复 CPSR中,这种操作主要用于从异常中断程序中返回。

2. CPSR中的【控制位】:

I,F,T,M

M的组合:

┏━━━┳━━━┓

┃M[4:0]┃ MODE ┃

┣━━━╋━━━┫

┃10000 ┃ USR ┃

┣━━━╋━━━┫

┃10001 ┃ FIQ ┃

┣━━━╋━━━┫

┃10010 ┃ IRQ ┃

┣━━━╋━━━┫

┃10011 ┃ SVE ┃

┣━━━╋━━━┫

┃10111 ┃ ABT ┃

┣━━━╋━━━┫

┃11011 ┃ UND ┃

┣━━━╋━━━┫

┃11111 ┃ SYS ┃

┗━━━┻━━━┛

301

302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359CHAP1.6 ARM体系的异常中断

1.ARM中异常中断种类:

┏━━━┳━━━┳━━━━━┓

┃优先级┃异常 ┃ 地址 ┃

┣━━━╋━━━╋━━━━━┫

┃ 1 ┃RESET ┃0x00000000┃

┣━━━╋━━━╋━━━━━┫

┃ 2 ┃D_ABT ┃0x00000010┃

┣━━━╋━━━╋━━━━━┫

┃ 3 ┃ FIQ ┃0x0000001C┃<----可以直接把FIQ的服务程序放在后面。

┣━━━╋━━━╋━━━━━┫

┃ 4 ┃ IRQ ┃0x00000018┃

┣━━━╋━━━╋━━━━━┫

┃ 5 ┃I_ABT ┃0x0000000C┃

┣━━━╋━━━╋━━━━━┫

┃ 6 ┃ UND ┃0x00000004┃

┣━━━╋━━━╋━━━━━┫

┃ 6 ┃ SWI ┃0x00000008┃

┗━━━┻━━━┻━━━━━┛

2.ARM处理器对异常中断的响应过程。

伪指令表示:

响应:

R14_ = return link ;保存返回地址

SPSR_ = CPSR ;保护当前CPSR

CPSR[5] = 0(T=0) ;中断自动回到ARM状态,且仅在ARM状态

if== reset or FIQ then ;禁止FIQ,IRQ

CPSR[6] = 1 ;如果时FIQ异常才禁止

CPSR[7] = 1 ;响应异常就禁止

PC = exception vector address ;跳转到异常服务程序的地址

返回:

CPSR = SPSR_

PC = Return link

CHAP1.7 ARM体系中的存储系统

1.ARM体系中的存储空间。

ARM体系使用FLAT模式的地址空间。

可以为2^32(即4GB)个字节。

2.ARM体系中的存储器格式。

*big-endian

┏━━━┳━━━┳━━━┳━━━┓

┃30 24┃23 16┃15 8┃7 0┃

┣━━━╋━━━╋━━━╋━━━┫

┃ 1 ┃ 2 ┃ 3 ┃ 4 ┃<----数据为:1234

┗━━━┻━━━┻━━━┻━━━┛

*little-endian

┏━━━┳━━━┳━━━┳━━━┓

┃30 24┃23 16┃15 8┃7 0┃

┣━━━╋━━━╋━━━╋━━━┫

┃ 4 ┃ 3 ┃ 2 ┃ 1 ┃<----数据为:1234

┗━━━┻━━━┻━━━┻━━━┛

3.非对齐的存储器访问操作。

*非对齐的指令预取操作:

在ARM状态下非对齐即地址的最末两位不为00,要么指令执行的结果不可预知 要么最后两位就会被忽略。同理可得THUMB状态的情况。

*非对齐的数据预取操作:

361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419

*忽略字单元的最低两位值。即Address and 0xfffffffc。

忽略半字单元的最低位值。即Address and 0xfffffffe。

*忽略字、半字单元的低位无效值。由存储器系统完成。

4.指令预取和自修改代码。

/********************************************************************************* /*********************************************************************************第二章 ARM指令分类及其寻址方式

CHAP2.1 ARM指令集概要介绍

1.ARM指令的分类: 6种

*跳转指令

*数据处理指令

*程序状态寄存器传输指令

*Load/Store指令

*协处理器指令

*异常中断产生指令

2.ARM指令的一般编码格式

┏━━━┳━━━┳━━━┳━┳━━━┳━━━┳━━━━━━━━┓

┃31-28 ┃27-25 ┃24-21 ┃20┃19-16 ┃15-12 ┃ 11-0 ┃

┣━━━╋━━━╋━━━╋━╋━━━╋━━━╋━━━━━━━━┫

┃cond ┃ 001 ┃opcode┃s ┃ Rn ┃ Rd ┃Shifter_operand ┃

┗━┳━┻━┳━┻━┳━┻┳┻━┳━┻━┳━┻━━━━┳━━━┛

┃ ┃ ┃ ┃ ┃ ┃ ┃

┃ ┃ ┃ ┃ ┃ ┃ ┗第二操作数

┃ ┃ ┃ ┃ ┃ ┗目的寄存器编码

┃ ┃ ┃ ┃ ┗第一操作数编码

┃ ┃ ┃ ┗影响标志

┃ ┃ ┗操作符

┃ ┗固定编码

┗条件

3.ARM指令的条件码域

┏━━┳━━━┳━━━━━━━━┳━━━━━━━━━━┓

┃条件┃助记符┃ 含义 ┃ CPSR条件标志位 ┃

┣━━╋━━━╋━━━━━━━━╋━━━━━━━━━━┫

┃0000┃ EQ ┃ 相等 ┃ Z=1 ┃

┣━━╋━━━╋━━━━━━━━╋━━━━━━━━━━┫

┃0001┃ NE ┃ 不相等 ┃ Z=0 ┃

┣━━╋━━━╋━━━━━━━━╋━━━━━━━━━━┫

┃0010┃CS/HS ┃无符号数大于等于┃ C=1 ┃

┣━━╋━━━╋━━━━━━━━╋━━━━━━━━━━┫

┃0011┃CC/LO ┃无符号数小于 ┃ C=0 ┃

┣━━╋━━━╋━━━━━━━━╋━━━━━━━━━━┫

┃0100┃ MI ┃ 负数 ┃ N=1 ┃

┣━━╋━━━╋━━━━━━━━╋━━━━━━━━━━┫

┃0101┃ PL ┃ 非负数 ┃ N=0 ┃

┣━━╋━━━╋━━━━━━━━╋━━━━━━━━━━┫

┃0110┃ VS ┃ 上溢出 ┃ V=1 ┃

┣━━╋━━━╋━━━━━━━━╋━━━━━━━━━━┫

┃0111┃ VC ┃ 无上溢出 ┃ V=0 ┃

┣━━╋━━━╋━━━━━━━━╋━━━━━━━━━━┫

┃1000┃ HI ┃无符号数大于 ┃ C=1且Z=0 ┃

┣━━╋━━━╋━━━━━━━━╋━━━━━━━━━━┫

┃1001┃ LS ┃无符号数小于等于┃ C=0或Z=1 ┃

┣━━╋━━━╋━━━━━━━━╋━━━━━━━━━━┫

┃1010┃ GE ┃有符号大于等于 ┃N=1且V=1 或N=0且V=0 ┃

421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479

┃1011┃ LT ┃有符号数小于 ┃N=1且V=0 或N=0且V=1 ┃

┣━━╋━━━╋━━━━━━━━╋━━━━━━━━━━┫

┃1100┃ GT ┃有符号数大于 ┃ Z=0且N=V ┃

┣━━╋━━━╋━━━━━━━━╋━━━━━━━━━━┫

┃1101┃ LE ┃有符号数小于等于┃ Z=1或N !=V ┃

┣━━╋━━━╋━━━━━━━━╋━━━━━━━━━━┫

┃1110┃ AL ┃无条件执行 ┃ ┃

┣━━╋━━━╋━━━━━━━━╋━━━━━━━━━━┫

┃1111┃ NV ┃该指令从不执行 ┃ ┃

┗━━┻━━━┻━━━━━━━━┻━━━━━━━━━━┛

CHAP2.2 ARM指令寻址方式

1.数据处理指令的操作数的寻址方式。

*立即数方式

*寄存器方式

*寄存器移位方式

2.字及无符号字节的LOAD/STORE指令的寻址方式。

各种类型的LOAD/STORE指令寻址方式由两部分组成。

A部分:基址寄存器。

B部分:地址偏移量。

地址偏移量可以由3种格式:

(1).立即数

(2).寄存器

(3).寄存器移位

以下各个位只是一些指令的,可能其他的不一样,不是标准。

┏━━━┳━━━┳━┳━┳━┳━┳━┳━┳━━━┳━━━┳━━━━━━┓ ┃31-28 ┃27-26 ┃25┃24┃23┃22┃21┃20┃19-16 ┃15-12 ┃ 11-0 ┃ ┣━━━╋━━━╋━╋━╋━╋━╋━╋━╋━━━╋━━━╋━━━━━━┫ ┃cond ┃ 01 ┃I ┃P ┃U ┃N ┃W ┃L ┃ Rn ┃ Rd ┃Address_mode┃ ┗━┳━┻━┳━┻┳┻┳┻┳┻┳┻┳┻┳┻━┳━┻━┳━┻━━┳━━━┛ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗

┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗

┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗

┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗操作的类型:L=1 STORE, L=0 LOAD ┃ ┃ ┃ ┃ ┃ ┃ ┗指令执行后,Rn值是否更新

┃ ┃ ┃ ┃ ┃ ┗由个协处理器决定,一般是传输数据的字节大小 ┃ ┃ ┃ ┃ ┗<+/->OFFSET_12

┃ ┃ ┃ ┗pre(预先的)

┃ ┃ ┗

┃ ┗固定

┗条件

3.杂类LOAD/STORE指令的寻址方式。

LDR|STR ,

/******************************************************************************/ /******************************************************************************/第三章 ARM指令集介绍

CAHP3.1 ARM指令集

1.跳转指令。

B及BL指令:

┏━━━┳━━━┳━━┳━━━━━━━━┓

┃31-28 ┃27-25 ┃24 ┃ 23-0 ┃

┣━━━╋━━━╋━━╋━━━━━━━━┫

┃cond ┃ 101 ┃ L ┃ signed_immed24 ┃

┗━━━┻━━━┻━━┻━━━━━━━━┛

481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539

跳转的范围大致为:-32MB ~ +32MB

返回:

*BX R14

*MOV PC,R14

*STMFD R13!,{,R14}

LDMFD R13!,{,PC}

Signed_immed24的来历:

(1).将PC寄存器的值作为本跳转指令的基地址值。

(2).从目的地址减去基地址形成偏移地址。

(3).当上面的偏移地址超过33554432~33554430时,程序需要做相应的处理。

(4).否则,将指令编码字中的Signed_immed24设置成上述字节偏移量的

bits[25:2]。

注意:当指令跳转地址越过0或32位地址空间最高地址时,将产生不可预测的结果 BLX(1)指令:

该指令完成跳转、保存PC到LR的同时切换处理器到THUMB状态。

┏━━━┳━━━┳━━┳━━━━━━━━┓

┃31-28 ┃27-25 ┃24 ┃ 23-0 ┃

┣━━━╋━━━╋━━╋━━━━━━━━┫

┃1111 ┃ 101 ┃ H ┃ signed_immed24 ┃

┗━━━┻━━━┻━━┻━━━━━━━━┛

返回:

*BX R14

*PUSH{,R14}

POP{,PC}

Signed_immed24的来历:

(1).将PC寄存器的值作为本跳转指令的基地址值。

(2).从目的地址减去基地址形成偏移地址。

(3).当上面的偏移地址超过33554432~33554430时,程序需要做相应的处理。

(4).否则,将指令编码字中的Signed_immed24设置成上述字节偏移量的

bits[25:2]。但是可知,现在转入了THUMB状态,所以要将H位设置成

上述字节偏移量的bit[1]。

注意:本指令时无条件执行的。

指令中的bit[24]被作为目标地址的bit[0]。

BLX(2)指令:

该指令完成跳转,目标地址处可以时ARM,THUMB指令。目标地址放在Rm中,该

地址的bit[0]为0,目标地址处的指令类型有CPSR中的T位决定。

指令的伪代码:

if Cond passed then

LR = address of instruction after the BLX instruction

T = Rm[0]

PC = Rm AND 0xfffffffe

BX指令:

和以上的BLX(2)指令类似,只是不对LR操作。

指令的伪代码为:

if cond passed then

T = Rm[0]

PC = Rm AND 0xfffffffe

2.数据处理指令。

*数据传送指令

MOV,MVN

541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599

AND,EOR,ORR,ADD,SKUB,RSB,ADC,SBC,RSC,BIC

*比较指令

CMP,TST,TEQ

---->MOV指令:

指令操作的伪代码:

if cond passed then

Rd = shifter_operand

if S==1 and Rd==R15 then

CPSR = SPSR

else if S==1 then

N = Rd[31]

Z = if Rd==0 then 1

else 0

C = shifter_carry_out

V = unaffected

MOV指令完成的功能:

*将数据从一个寄存器传送到另外一个寄存器

*将一个常数传送到另外一个寄存器中

*实现单纯的位移操作。左移操作可以实现将操作数乘以2^n。

*PC作为目标寄存器可以实现程序跳转。用于实现子程序调用和返回。

*PC作为目标寄存器且S位有效,则可以实现从某些异常中断中返回。 ---->MVN指令:

本指令的伪代码:

if cond passed then

Rd = NOT shifter_oprand <-----取反传送

if S==1 and Rd==R15 then

CPSR = SPSR

else if S==1 then

N = Rd[31]

Z = if Rd==0 then 1

else 0

C = shifter_carry_out

V = unaffected

MVN指令完成的功能:

*向寄存器中传送一个负数。

*生成位掩码。

*求一个数的反码。

---->ADD指令:

本指令的伪代码:

if cond passed then

Rd = Rn + shifter_oprand

if S==1 and Rd==R15 then

CPSR = SPSR

else if S==1 then

N = Rd[31]

Z = if Rd==0 then 1

else 0

C = carryfrom(Rn + shifter_oprand)

V = overflowfrom(Rn + shifter_oprand)

ADD指令完成的功能:

*完成两个操作数相加。

---->ADC指令:

本指令的伪代码:

if cond passed then

601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659

if S==1 and Rd==R15 then

CPSR = SPSR

else if S==1 then

N = Rd[31]

Z = if Rd==0 then 1

else 0

C = carryfrom(Rn + shifter_oprand + C)

V = overflowfrom(Rn + shifter_oprand + C)

ADC指令完成的功能:

*ADC和ADD指令联合使用可以实现两个64位的操作数相加。

如: ADD R0,R2 ; 具体的放置位置R1R0,R3R2

ADC R1,R3

---->SUB指令:

本指令的伪代码:

if cond passed then

Rd = Rn - shifter_oprand

if S==1 and Rd==R15 then

CPSR = SPSR

else if S==1 then

N = Rd[31]

Z = if Rd==0 then 1

else 0

C = NOT borrowfrom(Rn - shifter_oprand)<-----进位标志取反

V = overflowfrom(Rn - shifter_oprand)

SUB指令完成的功能:

*实现两个操作数相减。

*SUBS指令和条件跳转指令实现循环控制。

注意:在SUBS指令中,如果发生了借位操作,C标志位设置成0,反之,

C标志位设置为1。这和ADDS指令中的进位指令正好相反。这主要 是为了适应SBC指令的操作需要。

2008-1-27

---->SBC指令:

本指令的伪代码:

if cond passed then

Rd = Rn - shifter_oprand - NOT C<-----进位标志取反

if S==1 and Rd==R15 then

CPSR = SPSR

else if S==1 then

N = Rd[31]

Z = if Rd==0 then 1

else 0

C = NOT borrowfrom(Rn - shifter_oprand - NOT C)

V = overflowfrom(Rn - shifter_oprand - NOT C)

SBC指令完成的功能:

*SUB和SBC指令联合使用可以实现两个64位的操作数相减。

如: SUBS R4,R0,R2 ; 具体源操作数的放置位置 R1R0,R3R2

SBC R5,R1,R3 ; 结果操作数放置位置 R5R4

注意:在SBCS中,如果发生了借位操作,CPSR寄存器中的C标志位设置成0。

如果没有发生借位操作,CPSR寄存器中的C标志位设置成1。这个于 ADDS指令中的进位指令正好相反。

---->RSB逆向减法指令:

指令操作的伪代码:

if cond passed then

Rd = shifter_oprand - Rn

if S==1 and Rd==R15 then

CPSR = SPSR

661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719

N = Rd[31]

Z = if Rd==0 then 1

else 0

C = NOT borrowfrom(shifter_oprand - Rn)

V = overflowfrom(shifter_oprand - Rn)

RSB指令完成的功能:

*RSB Rd,Rx,#0 ; Rd = 0 - Rx <---------逆向相减

RSB Rd,Rx,Ry,LSL#n ; Rd = RY*2^n - Rx

注意:RSBS指令中如果发生借位,C位将被设置为0,反之设置为1。这个和 ADDS指令发生进位C的设置是相反的。主要是为了配合SBC指令的需要。 ---->RSC带借位逆向减法指令:

指令操作的伪代码:

if cond passed then

Rd = shifter_oprand - Rn - NOT C

if S==1 and Rd==R15 then

CPSR = SPSR

else if S==1 then

N = Rd[31]

Z = if Rd==0 then 1

else 0

C = NOT borrowfrom(shifter_oprand - Rn - NOT C)

V = overflowfrom(shifter_oprand - Rn - NOT C)

RSB指令完成的功能:

下面的指令序列可以求一个64位数值的负数。

*RSBS R4,R2,R0 ; 减数:R3R2,被减数:R1R0

RSC R5,R3,R1 ; 结果:R5R4

注意:RSCS指令中如果发生借位,C位将被设置为0,反之设置为1。这个和 ADDS指令发生进位C的设置是相反的。主要是为了配合SBC指令的需要。 ---->AND逻辑与操作指令:

指令操作的伪代码:

if cond passed then

Rd = Rn AND shifter_oprand

if S==1 and Rd==R15 then

CPSR=SPSR

else if S==1 then

N = Rd[31]

Z = if Rd==0 then 1

else 0

C = shifter_carry_out

V = unaffected

AND指令完成的功能:

*提取某些位,也就是保留某些位。要保留的用1与,要清除的用0与。

---->ORR逻辑或指令:

指令的伪代码:

if cond passed then

Rd = Rn OR shifter_oprand

if S==1 and Rd==R15 then

CPSR = SPSR

else if S==1 then

N = Rd[31]

Z = if Rd == then 1

else 0

C = shifter_carry_out

V = unaffected

ORR指令完成的g功能:

721

722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 ---->EOR逻辑或指令:

指令的伪代码:

if cond passed then

Rd = Rn EOR shifter_oprand

if S==1 and Rd==R15 then

CPSR = SPSR

else if S==1 then

N = Rd[31]

Z = if Rd == then 1

else 0

C = shifter_carry_out

V = unaffected

EOR指令完成的功能:

*把某些位取反,要取反的就和1异或,保留的用0异或。

---->BIC位清除指令:

指令的伪代码:

if cond passed then

Rd = Rn AND NOT shifter_oprand

if S==1 and Rd==R15 then

CPSR = SPSR

else if S==1 then

N = Rd[31]

Z = if Rd == then 1

else 0

C = shifter_carry_out

V = unaffected

ORR指令完成的功能:

*将某些位置0。要置0的位用1,保留不变的用0。

---->CMP比较指令:

指令的伪代码:

if cond passed then

alu_out = Rn - shifter_oprand <----不保存结果

if S==1 and Rd==R15 then

CPSR = SPSR

else if S==1 then

N = alu_out[31]

Z = if alu_out == then 1

else 0

C = NOT borrowfrom(Rn - shifter_oprand)

V = overflowfrom(Rn - shifter_oprand)

ORR指令完成的g功能:

*只影响CPSR中的标志位,结果不保存。和SUBS类似。

---->CMN比较指令:

指令的伪代码:

if cond passed then

alu_out = Rn + shifter_oprand <----不保存结果

N = alu_out[31]

Z = if alu_out == then 1

else 0

C = NOT carryfrom(Rn + shifter_oprand)

V = overflowfrom(Rn + shifter_oprand)

ORR指令完成的功能:

*CMN指令将寄存器Rn中的值加上shifter_oprand表示的数值,根据加法操作 的结果设置CPSR中相应的条件标志位。

注意:寄存器Rn中的值减去shifter_oprand表示的数值对CPSR中条件标志位

781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839

志位的影响有细微的差别。当第2个操作数为0或者为0x80000000时二

者结果不同,如:

CMP Rn, #0 ; C=1

CMN Rn, #0 ; C=0

---->TST位测试指令:

指令操作的伪代码:

if cond passed then

alu_out = Rn AND shifter_oprand

N flag = alu_out[31]

Z flag = if alu_out==0 then 1

else 0

C = shifter_carry_out

V = unaffected

TST指令完成的功能:

*测试某些位是1还时0。

---->TEQ相等测试指令:

if cond passed then

alu_out = Rn EOR shifter_oprand

N = alu_out[31]

Z = if alu_out==0 then 1

else 0

C = shifter_carry_out

V = unaffected

TEQ指令完成的功能:

*比较两个数是否相等,这种比较操作通常不影响CPSR寄存器中V位和C位。

*TEQ指令可以用于比较两个操作数的符号是否相同,该指令执行后,CPSR

寄存器中N位为两个操作数符号位异或操作的结果。

3.乘法指令

*MUL 32位乘法指令

*MLA 32位带加数的乘法指令

*SMULL 64位有符号数乘法指令

*SMLAL 64位带加数的有符号数乘法指令

*UMULL 64位无符号数乘法指令

*UMLAL 64位带加数的无符号数乘法指令

---->MUL指令:

if cond passed then

Rd = (Rm * Rs)[31:0]

if S==1 then

N = Rd[31]

Z = if Rd==0 then 1

else 0

C = unaffected

V = unaffected

MUL指令的使用:

*由于32位的数相乘结果是64位的,而MUL指令仅仅保存了64位结果的低32位, 所以对于带符号的和无符号的操作数来说MUL指令执行的结果相同。

*对于ARM v5及以上的版本,MULS指令不影响CPSR寄存器中的C条件标志位。

对于以前的版本,MULS指令执行后,CPSR寄存器中的C条件标志位数值是不

确定的。

*寄存器Rm,Rn,Rd为R15时,指令执行的结果不可预测。

MUL R0,R1,R2 ; R0=R1*R2

MULS R0,R1,R2 ; R0=R1*R2,调试设置CPSR中的N、Z位

841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899

if cond passed then

Rd = (Rm * Rs)[31:0]

if S==1 then

N = Rd[31]

Z = if Rd==0 then 1

else 0

C = unaffected

V = unaffected

MLA指令的使用:

*由于32位的数相乘结果是64位的,而MUL指令仅仅保存了64位结果的低32位, 所以对于带符号的和无符号的操作数来说MUL指令执行的结果相同。

*对于ARM v5及以上的版本,MLA指令不影响CPSR寄存器中的C条件标志位。

对于以前的版本,MLA指令执行后,CPSR寄存器中的C条件标志位数值是不

确定的。

*寄存器Rm,Rn,Rd为R15时,指令执行的结果不可预测。

MLA R0,R1,R2,R3 ; R0=R1*R2+R3

---->SMULL指令:

if cond passed then

RdHI = (Rm * Rs)[63:32]

RdLO = (Rm * Rs)[31:0]

if S==1 then

N = RdHI[31]

Z = if (RdHI==0) and (RdLO==0)then 1

else 0

C = unaffected

V = unaffected

SMULL指令的使用:

*对于ARM v5及以上的版本,SMULL指令不影响CPSR寄存器中的C条件标志位。

对于以前的版本,SMULL指令执行后,CPSR寄存器中的C条件标志位数值是不 确定的。

*寄存器Rm,Rn,Rd为R15时,指令执行的结果不可预测。

SMULL R1,R2,R3,R4 ; R1=(R3*R4)的低32位,R2=(R3*R4)的高32位。

---->SMLAL指令:

if cond passed then

RdLO = (Rm * Rs)[31:0]

RdHI = (Rm * Rs)[63:32]+RdHI+carryfrom((Rm*Rs)[31:0]+RdLO)

if S==1 then

N = RdHI[31]

Z = if (RdHI==0) and (RdLO==0)then 1

else 0

C = unaffected

V = unaffected

SMLAL指令的使用:

*对于ARM v5及以上的版本,SMLAL指令不影响CPSR寄存器中的C条件标志位。

对于以前的版本,SMLAL指令执行后,CPSR寄存器中的C条件标志位数值是不 确定的。

*寄存器Rm,Rn,Rd为R15时,指令执行的结果不可预测。

---->UMULL指令:

if cond passed then

RdHI = (Rm*Rs)[63:32]

RdLO = (Rm*Rs)[31:0]

if S==1 then

N = RdHI[31]

Z = if (RdHI==0) and (RdLO==0) then 1

else 0

C = unaffected

901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 UMULL指令完成的功能:

*对于ARM v5及以上的版本,UMULLS指令不影响CPSR中C条件标志和V条件标志 对于以前的版本UMULLS指令执行后,CPSR寄存器中的C条件标志位数值是不 确定的。

*寄存器Rm,Rn,RdLO,RdHI位R15时指令的执行结果不可预测。

---->UMLAL指令:

if cond passed then

RdLO = (Rm*Rs)[31:0] + RdLO

RdHI = (Rm*Rs)[63:32] + RdHI + carryfrom((Rm*Rs)[31:0]+RdLO)

if S==1 then

N = RdHI[31]

Z = if (RdHI==0) and (RdLO==0) then 1

else 0

C = unaffected

V = unaffected

UMLAL指令完成的功能:

*对于ARM v5及以上的版本,UMLALS指令不影响CPSR中C条件标志和V条件标志 对于以前的版本UMLALS指令执行后,CPSR寄存器中的C条件标志位数值是不 确定的。

*寄存器Rm,Rn,RdLO,RdHI位R15时指令的执行结果不可预测。

4.杂类的算术指令

---->CLZ指令:

本条指令主要用于计算操作数最高端0位的个数。主要用于两种场合:

A.计算操作数规范化(使其最高位为1)时所需要左移的位数。

B.确定一个优先级掩码中最高优先级(最高位的优先级)。

指令的语法格式:

CLZ ,

指令操作的伪代码:

if Rm==0

Rd==32

else

Rd = 31-(bit position of most significant "1" in Rm)

指令的使用:

CLZ Rd,Rm

MOVS Rm,Rm,LSL Rdl

5.状态寄存器访问指令

*MRS Register <--- CPSR

*MSR CPSR <--- Register

---->MRS指令:

本指令的伪代码:

if cond passed then

if R==1 then

Rd = SPSR

else

Rd = CPSR

本指令应用场合:

*通常通过"读-修改-写"操作序列修改状态寄存器的内容。

*当异常中断允许嵌套时,需要在进入异常中断之后,嵌套中断发生之前

处理器模式对应的SPSR。这时需要通过MRS指令读出SPSR的值,再用其他

指令将SPSR值保存起来。

*在进程切换时也需要保存当前状态寄存器的值。

---->MSR指令:

本指令的伪代码:

if cond passed then

961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019

operand = 8_bit_immediate rotate_right (rotate_imm * 2)

else

operaand = Rm

if R==0 then

if field_mask[0] == 1 and InAPrivilegedMode() then

CPSR[7:0] = operand[7:0]

if field_mask[1] == 1 and InAPrivilegedMode() then CPSR[15:8] = operand[7:0]

if field_mask[2] == 1 and InAPrivilegedMode() then CPSR[23:16] = operand[7:0]

if field_mask[3] == 1 and InAPrivilegedMode() then CPSR[31:24] = operand[7:0]

else

if field_mask[0] == 1 and CurrentModeHasSPSR() then

CPSR[7:0] = operand[7:0]

if field_mask[1] == 1 and CurrentModeHasSPSR() then CPSR[15:8] = operand[7:0]

if field_mask[2] == 1 and CurrentModeHasSPSR() then CPSR[23:16] = operand[7:0]

if field_mask[3] == 1 and CurrentModeHasSPSR() then CPSR[31:24] = operand[7:0]

本指令应用场合:

*本指令通常用于恢复PSR的内容和改变PSR的内容。

*当退出异常中断时,如果事先保存了PSR的内容通常通过MSR指令将事先 保存的状态寄存器恢复到PSR中。

*当需要修改PSR的内容时,通过"读-修改-写"指令序列完成。

*考虑到指令的执行效率,通常在MSR指令中指定指令将要修改的位域。

但是,当进程切换到应用场合,应指定SPSR_fsxc,这样将来ARM扩展了当

前未用的一些位后,程序还可以正常的运行。

*当需要修改PSR位域包含未分配的位时,最好不要使用带立即数方式的 MSR指令。

6.LOAD/STORE内存访问指令

*LDR 字加载

*LDRB 字节加载

*LDRBT 用户模式的字节数据加载

*LDRH 半字加载

*LDRSB 有符号字节数据加载

*LDRSH 有符号半字数据加载

*LDRT 用户模式的字数据加载

*STR 字写入

*STRB 字节写入

*STRBT 用户模式的字节写入

*STRH 半字写入

*STRT 用户模式的字写入

---->LDR指令:

本指令伪代码:

if cond passed then

if address[1:0] == 0b00 then

value = Memory[address, 4]

else if address[1:0] == 0b01 then

value = Memory[address,4] rotate_right 8

else if address[1:0] == 0b10 then

value = Memory[address,4] rotate_right 16

else

value = Memory[address,4] rotate_right 24

if (Rd is R15) then

1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079

PC = value AND 0xfffffffe

T = value[0]

else

PC = value AND 0xfffffffc

else

Rd = value

本指令的使用:

*用于从内存中读取32位字数据到通用寄存器中,然后可以在该寄存器中 对该数据进行一定的操作。

*当PC作为指令中的目标寄存器时,指令可以实现程序跳转的功能。

当PC作为LDR指令的目标寄存器时,指令从内存中读取到的字数据当被当作 目标地制值。指令执行后,将从目标地址处开始执行。在ARMv5及其以上 版本中,地址值的bit[0]用来指示目标地址处程序的状态,当bit[0]为1时 目标地址的指令为THUMB指令,同理,当bit[0]为0时目标地址处的指令为 ARM指令。在ARMv5以上的版本中地址值的bit[0]将被忽略,程序将继续 执行在ARM状态下。

指令示例:

*LDR R0,[R1,#4] ;R0 = [R1+4]

*LDR R0,[R1,-#4] ;R0 = [R1-4]

*LDR R0,[R1,R2] ;R0 = [R1+R2]

*LDR R0,[R1,R2,LSL #2] ;R0 = [R1+R2*4]

*LDR R0,[R1,#4]! ;R0 = [R1+4],R1 = R1+4

*LDR R0,[R1,-#4] ;R0 = [R1-4],R1 = R1-4

*LDR R0,[R1],#4 ;R0 = [R1],R1 = R1+4

*LDR R0,[R1],R2 ;R0 = [R1],R1 = R1+R2

*LDR R0,[R1],R2,LSL #2 ;R0 = [R1],R1 = R1+R2*4

---->LDRB指令:

本指令伪代码:

if cond passed then

Rd = Memory[address,1]

本指令的使用:

*用于从内存中读取8位字节数据到通用寄存器中,然后可以在该寄存器中 对该数据进行一定的操作。

*当PC作为指令中的目标寄存器时,指令可以实现程序跳转的功能。

指令示例:

*LDRB R0,[R2,#3] ;R0[7:0] = [R2+3],R0[31:8] = 0

---->LDRBT指令:

本指令伪代码:

if cond passed then

Rd = Memory[address,1]

本指令的使用:

*用于从内存中读取8位字节数据到通用寄存器中,然后可以在该寄存器中 对该数据进行一定的操作。

*当在特权级别的处理器模式下使用该指令,内存系统将该操作当作时一般 用户模式下的内存访问操作。

指令示例:(注意模式)

*LDRBT R0,[R2,#3] ;R0[7:0] = [R2+3],R0[31:8] = 0

---->LDRH指令:

本指令伪代码:

if cond passed then

if address[0] = 0

data = Memory[address,2]

else

1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139

Rd = data

本指令的使用:

*用于从内存中读取16位半字数据到通用寄存器中,然后可以在该寄存器中

对该数据进行一定的操作。

*当PC作为指令中的目标寄存器时,指令可以实现程序跳转的功能。

指令示例:

*LDRH R0,[R2,#3] ;R0[15:0] = [R2+3],R0[31:16] = 0

---->LDRSB指令:

本指令伪代码:

if cond passed then

data = Memory[address,1]

Rd = SignExtend(data)

本指令的使用:

*用于从内存中读取8位有符号的字节数据到通用寄存器,然后在该寄存器中 用该8位符号数的符号位填充高24位,将其扩展成32位有符号数。

*PC作为目标寄存器时,指令可以实现程序跳转的功能。

指令示例:

*LDRSB R0,[R2,#3] ;R0[7:0] = [R2+3],R0[31:8] = 字节符号

---->LDRSH指令:

本指令伪代码:

if cond passed then

if address[0] = 0

data = Memory[address,2]

else

data = UNPREDICTABLE

Rd = SignExtend(data)

本指令的使用:

*用于从内存中读取16位有符号的半字数据到通用寄存器,然后在该寄存器中 用该16位符号数的符号位填充高16位,将其扩展成32位有符号数。

*PC作为目标寄存器时,指令可以实现程序跳转的功能。

指令示例:

*LDRSH R0,[R2,#3] ;R0[15:0] = [R2+3],R0[31:16] = 字节符号

---->LDRT指令:

本指令伪代码:

if cond passed then

if address[1:0] == 0b00

Rd = Memory[address,4]

else if address[1:0] == 0b01

Rd = Memory[address,4] rotate_right 8

else if address[1:0] == 0b10

Rd = Memory[address,4] rotate_right 16

else

Rd = Memory[address,4] rotate_right 24

本指令的使用:

*用于从内存中读取一个32位的字数据到目标寄存器中,如果指令中的寻址方式 确定的地址不时字对齐的,则从内存中读出的数值要进行循环右移操作。移位

的位数为寻址方式确定的地址bits[1:0]的8倍。这样对于little-endian的内存 模式想要读取的字节数据存放在目标寄存器的低8位;对于big-endian的内存模 式想要读取的字节数据存放在目标寄存器的bits[32:24](寻址方式确定的地址

bit[0]为0)或者存放在bits[15:8](寻址方式确定的地址bit[0]为1)

*当处在特权级处理器模式下使用本指令时,内存系统将该操作当作一般用户

模式下的内存操作。

指令示例:

---->STR指令

1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199

if cond passed then

Memory[address,4] = Rd

本指令的使用:

*用于将一个32位的字数据写入到指令指定的内存单元。

指令示例:

STR R0,[R1,#0X100] ; R0 ---> [R1+0X100]

STR R0,[R1],#8 ; R0 ---> [R1], R1 = R1+8

---->STRB指令

本指令的伪代码:

if cond passed then

Memory[address,1] = Rd[7:0]

本指令的使用:

*用于将一个32位的字数据写入到指令指定的内存单元。

指令示例:

STR R0,[R1,#0X100] ; R0 ---> [R1+0X100]单元的低8位

STR R0,[R1],#8 ; R0 ---> [R1]单元低8位, R1 = R1+8

---->STRH指令

本指令的伪代码:

if cond passed then

if address[0] = 0

data = Rd[15:0]

else

data = UNPREDICTABLE

Memory[address,2] = data

本指令的使用:

*用于将寄存器低16位半字数据写入到指令指定的内存单元。

指令示例:

STR R0,[R1,#0X100] ; R0 ---> [R1+0X100]

@ STR R0,[R1],#8 ; R0 ---> [R1], R1 = R1+8

---->STRT指令

本指令的伪代码:

if cond passed then

Memory[address,4] = Rd

本指令的使用:

*异常中断程序在特权级的处理器模式下执行,这时如果需要按照用户模式 的权限内存访问操作。

指令示例:

STR R0,[R1,#0X100] ; R0 ---> [R1+0X100]

STR R0,[R1],#8 ; R0 ---> [R1], R1 = R1+8

7.批量LOAD/STORE内存访问指令

*LDM(1) 批量内存字数据读取指令

*LDM(2) 用户模式的批量内存字数据

*LDM(3) 带状态寄存器的批量内存字数据读取指令

*STM(1) 批量内存字数据写入指令

*STM(2) 用户模式的批量内存字数据写入指令

---->LDM(1)指令

本指令的格式:

LDM{}{!},

本指令的伪代码:

if cond passed then

address = start_address

for i = 0 to 14

if register_list[i] == 1 then

Ri = Memory[address,4]

实验三 搭建嵌入式系统开发环境

实验三搭建嵌入式系统开发环境 一、实验目的: 1.掌握嵌入式开发环境的配置; 2.掌握开发工具链的安装与配置; 3.掌握嵌入式系统内核和根文件系统的烧写的过程。 二、实验内容: 1)安装配置嵌入式开发环境; 2)安装与配置工具链; 3)内核和根文件系统的烧写 三、实验设备及工具: 硬件:UP-NETARM2410-S嵌入式实验仪、PC机pentumn500以上、硬盘40G以上、内存大于256M。 软件:PC机操作系统Red Hat Enterprise Linux 4、MINICOM 、AMRLINUX开发环境。 四、实验步骤: 1.共享windows下内核文件至linux环境下,并将文件复制至个人开发目录中 2.进入目录,输入make menuconfig,对内核进行裁剪配置 3.编译内核之前输入make clean清理编译环境 4.输入make dep 编译相关依赖文件 5.输入make zImage 输出最终编译后的镜像文件 6.将镜像文件共享至windows环境下 7.在windows打开超级终端,进入vivi,将镜像文件烧录至实验箱开发板中 五、实验总结: 通过本次实验,熟悉了Linux 开发环境,学会了如何进行linux内核的烧写。在实验

过程中了解到Linux内核模块的组成结构,通过本次实验,初步了解嵌入式开发的基本过程。 实验四嵌入式驱动程序设计 一、实验目的: 1.学习在LINUX 下进行驱动设计的原理 2.掌握使用模块方式进行驱动开发调试的过程 二、实验内容: 在PC 机上编写简单的虚拟硬件驱动程序并进调试,实验驱动的各个接口函数的实现,分析并理解驱动与应用程序的交互过程。 三、实验设备及工具: 硬件:UP-NETARM2410-S嵌入式实验仪、PC机pentumn500以上、硬盘40G以上、内存大于256M。 软件:PC机操作系统Red Hat Enterprise Linux 4、MINICOM 、AMRLINUX开发环境。 四、预备知识: 1.有 C 语言基础。 2.掌握在Linux 下常用编辑器的使用。 3.掌握Makefile 的编写和使用。 4.掌握Linux 下的程序编译与交叉编译过程。 5.有驱动开发的基本知识。 五、实验步骤: 1.进入/arm2410cl/exp/drivers/01_demo,使用vi 编辑器或其他编辑器阅读理解源代码 2.使用makefile编译驱动模块与测试程序,编译器采用armv4l-unknown-linux-gcc 3.将编译后的驱动模块demo.o和测试程序test_demo挂载到实验箱上 4.插入驱动模块demo.o 执行命令insmod demo.o 5.查看驱动是否插入成功,执行命令lsmod demo.o 6.运行测试程序,查看执行结果

嵌入式Linux开发环境搭建

第一章Ubuntu 8.10的安装和网络配置 1.安装虚拟机软件Vmware 6.0.2 虚拟机安装版本Vmware 6.0.2的版本 在winxp操作系统下用鼠标双击VMware-workstation-6.0.2-59824图标,开始安装虚拟机Vmware,如下图所示: 双击VMware-workstation-6.0.2-59824图标,出现vmware的安装界面,所有的选项都采用默认值,用鼠标点【下一步】,然后出现安装进度条,系统开始安装vmware,等待安装完成后,出现如下安装完成界面: 用鼠标点【Finish】,虚拟机安装完成。系统提示重新启动计算机,选择【是】重新启动计算机,电脑重新启动后,虚拟机安装完成。 2.新建虚拟机 打开Vmware虚拟机软件,选【File】->【New】->【Virtual Machine】,弹出新建虚拟机向导对话框,注意以下几个重要的选项,其他都采用默认选项即可。 选择操作系统和版本,如下图所示:

选择虚拟机名称和存放的路径,如下图所示: 设置虚拟机硬盘大小为20G ,如下图所示:

点击【完成】按钮,这样我们就新建了一个虚拟机,下面我们设置一下虚拟机的内存,步骤如下: 点击虚拟机Vmware的【VM】->【settings】时菜单,弹出虚拟机设置对话框,设置虚拟机使用的内存为512M或1024M,如下图所示:

点击【OK】按钮,这样我们就新建了一个虚拟机,该虚拟机的硬盘为20G, 内存为512M .接着我们就可以在该虚拟机上安装ubuntu操作系统了。 注: 键盘和鼠标控制权在虚拟机和Windows系统之间的切换是通过组合键【Ctrl】+【Alt】来实现的。 3 安装Linux操作系统ubuntu Ubuntu安装版本ubuntu 8.10 点击vmware软件工具栏上的【绿色箭头】启动虚拟机,如下图所示:

建立嵌入式linux开发环境实验

嵌入式linux开发环境的建立 一、创建文件:vi hello.c如下: 二、安装交叉编译器: arm-linux-gcc-3.4.6-glibc-2.3.6.tar 步骤1、把交叉编译链考贝到任意目录下,并解压:tar zxvf arm-linux-gcc-3.4.6-glibc-2.3.6.tar –C / 2、把以上路径添加到/etc/profile文件的最后:export PATH=$PATH:/gcc-3.4.6-glibc-2.3.6/arm-linux/bin 3、输入命令使环境变量立即生效:source /tec/profile 4、测试是否安装成功:arm-linux-gcc–v 如果显示版本号,则安装成功。 5、编译C文件:arm-linux-gcc hello.c–o hello 三、配置tftp服务步骤

1、检查系统有无安装包:用命令:rpm –aq | grep tftp,如有安装包的版本号,说明系统已有相应的安装包; 2、配置服务器,打开文件:vi /etc/xinetd.d/tftp,显示如下桌面service tftp { socket_type = dgram protocol = udp wait = yes user = root server = /usr/sbin/in.tftpd server_args = -s /tftpboot disable = yes } 然后编辑将disable改为no,其他不变 3、重启xinetd服务:service xinetd restart, 停止 xinetd: [ 确定 ] 启动 xinetd: [ 确定 ] 4、输入如下命令:netstat –a | grep tftp,如果出现如下画面

实验三(ARM编程环境的熟悉及寻址方式实验)

实验三ARM编程环境熟悉及寻址方式实验 注意:本实验在模拟环境下进行!! 一、实验目的: 1、进一步熟悉ARM的编程工具MDK; 2、深刻理解ARM汇编指令中标号的本质; 3、熟悉ARM寻址方式(寄存器寻址、寄存器间接寻址等); 二、实验步骤: 1、参照实验二的步骤,建立工程exp 2、设置工程、建立源文件 exp2.s并将其添加到工程,在exp2.s中输入如下代码(可复制):;广州大学华软软件学院 ;文件名:exp2.s ;功能: ;作者: ;日期: ;修改: area init,code,readonly entry ldr r0,=data1;将标号data1的值送给r0 ldr r1,=data2; ldr r2,=data3 ldr r0,[r0]

ldr r1,[r1] add r0,r0,r1 str r0,[r2] b .;相当于while(1) data1 dcd 12;定义一个字,初值为12 data2 dcd 13;定义一个字,初值为13 data3 dcd 0;定义一个字,初值为0 end 2、编译正确后调试(可参照实验二),注意Ro_Base设置为 0x30000000,点击下图菜单中的菜单项,调出内存单元观察窗口。

会弹出如下界面:

点击current,就会看到当前模式下的寄存器 按F10进行单步调试,同时观察寄存器中的变化; 反汇编界面: 出现如下界面:鼠标右键,如图选中,即可看到源代码的反汇编窗口。

我们发现data1代表的地址是0x30000020,data2代表的地址是0x30000024,data3代表的地址是0x30000028。好,我们现在通过memory窗口来查看这些内存单元的内容: 在存储单元窗口输入0x30000020(如下图所示),观察存储单元中的 值,是不是我们程序所运行的结果呢?

嵌入式开发环境搭建步骤

嵌入式开发,通常都是在Linux环境下编译Uboot、Linux和android代码。编译uboot/Linux可以选择任何的Linux发行版,如redhat,suse,ubuntu,fedora,debian等,只要你配置好ARM交叉工具编译工具就可以了。 编译android,搭建环境最容易的就是ubuntu。google的官方网站上,也有搭建编译android的简单介绍,可以搜索下,网络上有相当多这方面的说明。 考虑到我们学习嵌入式的平台是Fast Models,以及自动的Realview EB模型硬件平台。而ARM官方推荐是在Redhat Enterprise(4,5,6)下安装Fast Models。所以,我们采用Redhat Enterprise 6作为开发环境。我们可以直接在电脑上安排RHEL6,也可以先安装vmware,然后在vmware中创建一个虚拟机,在虚拟机上安装RHEL6。在这里,小编是采用后者方式。 搭建Redhat Enterprise 6开发环境,建议做以下配置: 1)设置静态IP。在之前使用vmware的经历,发现如何网站采用dhcp方式,那么rhel6的IP地址有可能会发现改变。而我们需要网络IP最好是固定的,所以需要设置静态IP。RHEL6的静态IP的设置方法,可以搜索到。 2)开启ssh,samba服务 ARM嵌入式开发,基本上都是在命令(shell)方式下进行的,不需要图形界面。所以,在windows上运行vmware,vmware上虚拟机再运行rdel6的情况下,为了不增加windows系统的负荷,可以把vmware放在后台运行,使用ssh服务登陆到rdel6就可 以进行嵌入式开发了。 小编在开发嵌入式时,通常都是使用sourceinsight阅读、修改代码,然后在shell运 行命令进行编译。所以,开通samba服务,然后使用windows已安装的sourceinsight 工具,阅读放在rdel6上的Linux/uboot代码。 在Redhat发行版下,有关服务器的开启或关闭,可以在root用户下,使用setup命 令进入配置选项的“System Services”菜单下进行设置。 samba服务在菜单选项为:“smb”;ssh服务在菜单选项为:“sshd” 需要注意的是:windows下,要使用ssh服务/samba服务登陆vmware虚拟机上的rhel6,必须把rhel6上的防火墙关掉。setup命令--->Firewall Configuration--->去掉Enable。

实验1(嵌入式开发环境实验)

实验1:嵌入式Linux开发环境 一、实验目的 熟悉Linux开发环境,学会基于S3C2410的Linux开发环境的配置和使用。使用Linux的armv4l-unknown-linux-gcc编译,使用基于NFS方式的下载调试,了解嵌入式开发的基本过程。 二、实验内容 1、在linux系统下,利用C语言来编写应用程序,并进行交叉编译,生成可在目标实验台上运行的目标文件。 2、建立宿主机与目标实验台仿真终端连接,为目标实验台建立Linux系统终端窗口。 3、建立宿主机与目标实验台的共享连接,以便下载和运行最终可执行文件。 三、预备知识 C语言的基础知识、程序调试的基础知识和方法,Linux的基本操作。 四、实验设备及工具(包括软件调试工具) 硬件:UP-NETARM2410-S嵌入式实验平台、PC机Pentium 500以上, 硬盘10G以上。 软件:PC机操作系统REDHAT LINUX 9.0+MINICOM+ARM-LINUX开发环境 五、主要实验步骤: 1、打开PC宿主机电源,选择进入Linux系统。在PC宿主机的/arm2410s/exp/Basic目录中创建用户个人工作目录,例如“cao”。 2、单击鼠标右键选择“新建终端”,建立宿主机Linux命令终端窗口,在[root@localhost root]#命令提示符下进入个人工作目录“cao”中。 即:[root@localhost root]#cd /arm2410s/exp/basic/cao 3、利用“vi”编辑hello应用程序,并保存为hello.c文件。 即:#cd /arm2401s/exp/Basic/cao #vi hello.c 进入vi编辑窗口,编辑hello.c文件…… 4、利用“gcc –o”命令对hello.c文件进行编译,生成可在PC宿主机上执行的目标文件hello.pc。 即:#gcc –o hello.pc hello.c, 为了验证结果正确性,可在PC宿主机上执行hello.pc文件。 即:#./hello.pc 5、为了在实验台上下载运行hello文件,需要对hello源文件进行交叉编译,以便生成能够在实验台上运行的目标文件。利用“armv4l-unknown–Linux-gcc –o命令”进行交叉编译,生存目标文件hello.o。 即:# armv4l-unknown-Linux-gcc -o hello.o hello.c (注意:这里的“armv4l-unknown–Linux-gcc –o”交叉编译命令输入方法是使用键盘输

ARM实验报告

湖南科技学院ARM嵌入式设计实验报告题目:基于ARM嵌入式系统跑马灯的设计 专业:电子信息工程 班级:电信1102班 姓名:段相辉 学号:201106002232 指导教师:陈光辉 2014年11 月

目录 摘要............................................. 错误!未定义书签。ABSTRACT .......................................... Ⅰ错误!未定义书签。 1 题目要求 (1) 2 设计软件的安装 (2) 3 开发平台的搭建 (22) 4 项目设计 (23) 4.1 设计思路概述 (2) 4.1.1 设计层次介绍 (2) 4.1.2 设计模块介绍 (3) 5总结 (6) 致谢 (25) 参考文献 (26) 附录 (27)

引言 随着生活水平的提高和IT技术的进步,8位处理器的处理能力已经不能满足嵌入式系统的需要了;而16位处理器在性能和成本上都没有很大的突破。并且在8位机的开发中,大多使用汇编语言来编写用户程序。这使得程序的可维护性、易移植性等都受到了极大的挑战。正是基于此,ARM公司适时的推出了一系列的32位嵌入式微控制器。目前广泛使用的是ARM7和ARM9系列,ARM7TDMI内核的ARM7处理器广泛应用于工业控制、仪器仪表、汽车电子、通讯、消费电子等嵌入式设备。

1、题目要求 构建嵌入式Linux开发环境,熟悉linux的命令操作,并在嵌入式Linux 开发环境中设计跑马灯。 2、设计软件的安装 2.1 VMware Player简介 (a) VMware Workstation是一个“虚拟机”软件.它使用户可以在一台机 器上同时运行多个操作系统. (b) VMware Player是VMware Workstation的精简版,最初只是虚拟机的“播放机”, 但最新版本的已经具有创建虚拟机的功能.具有体积小,使用灵活,免费等特点. (c) 多个操作系统在主系统的平台上,可像Windows应用程序那样切换.而且每个操作系统都可以进行虚拟的分区、配置而不影响真实硬盘的数据. (d) 利VMware Player创建虚拟机

嵌入式系统开发环境实验

嵌入式系统开发环境实验 一实验目的与要求 1.熟悉Linux系统环境。 2.了解实验板的结构组成。 3.了解嵌入式系统开发的基本知识。 4. 熟悉嵌入式Linux交叉编译环境的建立过程,并通过一个HelloWorld程序的编写、编译、下载运行及调试过程,了解嵌入式开发的基本方法和流程。 二实验设备与软件环境 1.硬件:SemitARM9200开发板,PC机PIII800MHz,256MB以上,串口线(公母)1条,网线1条,7.5V 电源1个。 2.软件:RedHat 9.0以上Linux操作系统. 三实验原理 1.宿主机开发环境 绝大多数的Linux软件开发都是以Native方式进行的,即本机(Host)开发、调试,本机运行的方式。这种方式通常不适合于嵌入式系统的软件开发,因为嵌入式系统没有足够的资源在本机(即板子上系统)运行开发工具和调试工具。通常的嵌入式系统的软件开发采用一种交叉编译调试的方式,交叉编译调试环境建立在宿主机(即一台PC机)上,对应的开发板叫做目标板。如下图所示。 开发时使用宿主机上的交叉编译、汇编及链接工具形成可执行的二进制代码,(这种可执行代码不能在宿主机上执行,而只能在目标板上执行)然后把可执行文件下载到目标机上运行。一般调试的方法包括串口调试和以太网口调试。对于本实验板,目前可采用串口调试,操作系统经过修改可以实现以太网口调试。宿主机和目标板的处理器一般都不相同,宿主机为Intel或AMD处理器,而目标板如本实验板的处理器为ATMEL AT91RM9200 。GNU编译器提供这样的功能,在编译时可以选择开发所需的宿主机和目标机从而建立开发环境。所以在进行嵌入式开发前第一步的工作就是要安装一台装有指定操作系统的PC机作宿主开发机,宿主机上的操作系统一般要求安装Linux,但Linux由多个发行版本,在此,我们推荐使用Redhat 9.0作为本实验板的宿主机PC操作系统(https://www.doczj.com/doc/e814277908.html,可以下载)。然后要在宿主机上建立交叉编译调试的开发环境。环境的建立需要许多的软件模块协同工作,这将是一个比较繁杂的工作,但现在只要安装我们提供的光盘,开发软件包及GNU编译工具已完全自动完成了。 当开发环境安装完毕后,会在根目录下生成两个目录:工作目录/home/arm和交叉编译环境目录/usr/local/arm。

ARM开发环境搭建 eclipse for arm实验报告

实验报告 实验题目 ARM开发环境搭建 eclipse for arm 姓名: 学号: 课程名称: 所在学院: 专业班级: 任课教师:

一、实验目的与要求: 1、掌握 ARM 汇编语言的基本使用和一些伪指令的使用; 2、熟悉 eclipse 开发工具建立汇编工程和仿真;

四、实验过程、步骤及内容 1、win7环境安装FS_JTAG工具 (1)安装GCC 编译工具 双击安装“华清远见-CORTEXA9 资料\工具软件\Windows\FS-JTAG\Yagarto 工具包”目录下的文件:yagarto-bu-2.21_gcc-4.6.2-c-c++_nl-1.190_gdb-7.3.1_eabi_20111119.exe (2)装Yagarto 工具包 双击安装“华清远见-CORTEXA9 资料\工具软件\Windows\FS-JTAG\Yagarto 工具包”目录下的文件:yagarto-tools-20100703-setup.exe (3)安装FS_JTAG调试软件 双击“x包”下的setup.exe安装 FS_JTAG工具 (4)安装FS_JTAG驱动

将FS_JTAG通过USB线与PC连接,右键点击“我的电脑”选择“管理”,在左侧栏里选择“设备管理”选择“其他设备”右键点击选择“更新驱动” 选择“浏览计算机以查询驱动程序软件(R)”; 点击浏览选择“FS-JTAG 调试工具(安装包)\DRIVER”目录主要“包括子文件夹”必须选择,点击“下一步”。 安装过程出现上图提示,点击“始终安装此驱动程序软件(I)“继续安装

点击“关闭“完成安装 注意:此安装过程需要进行 3 次,直到设备管理器中没有叹号标记或未知设备。这是设备管理器中会出现如下选项:如果下面选项没有全部出现,右键点击有黄色叹号的选项更新驱动,过程同上。 (5)安装JRE 双击安装“华清远见-CORTEXA9 资料\ 工具软件\Windows\FS-JTAG\JRE ”目录下的文件: jre-6u7-windows-i586-p-s.exe

ARM嵌入式系统实验实验一参考答案(ADS1.2集成开发环境练习实验)

ARM嵌入式系统实验实验一参考答案(ADS1.2集成开发环境练习实验) 1.实验目的 了解ADS1.2 集成开发环境的使用方法。 2.实验设备 硬件:PC机一台 软件:Windows98/XP/2000 系统,ADS1.2集成开发环境 3.实验内容 (1)建立一个新的工程。 (2)建立一个汇编文件,并添加到工程中。 (3)设置文本编辑器支持中文。 (4)设置编译链接控制选项。 (5)编译链接工程。 (6)调试工程。 4.实验步骤 (1)在D:\新建一个目录,目录名为experiment。启动ADS1.2 IDE集成开发环境,选择【File】-> 【New...】,使用ARM Executalbe Image工程模板建立一个工程,工程名称为ADS,工程目录为D:\experiment。 (2)选择【File】-> 【New…】建立一个新的文件test1.s,设置直接添加到项目中。输入实验程序并保存,此时在工程窗口中可以看到test1.s文件了。 (3)由于ADS安装以后默认字体是Courier New,对于中文支持不完善,因此建议修改字体。选择【Edit】-> 【Perferences…】,在其中的Font选项中设置字体为Fixedays,Script 是CHINESE_GB2312,另外由于Tab在不同文本编辑器解释不同,建议在Tab Inserts Spaces 前打勾,使Tab键插入的是多个空格。 (4)选择【Edit】->【DebugRel Settings…】,在弹出的对话框的左边选择ARM Linker 项,然后在Output页设置链接地址为Simple,其中Ro Base为0x40000000,RW Base为0x40003000;并设置Option页中Image entry Point地址为0x40000000. (5)选择【Project】-> 【Make】,编译链接整个工程,如果编译成功,则Errors&Warnings 对话框会报告编译错误为0,那么就可以对工程进行仿真了。 (6)选择【Project】-> 【Debug】,或者按下F5。IDE环境将会启动AXD调试软件,接着便可以执行单步、全速运行调试。注意,要在AXD的Choose Target窗口中选用ARMUL 软件仿真。断点调试方法:首先设置断点,只需要在第6行灰色区域双击鼠标即可,如果出现红色实心圆点,那么表示断点设置成功,然后选择【Execute】-> 【Go】全速运行可以发现程序停止在第6行。还有一种比较方便的调试方法就是Run to Cursor,单击鼠标第8行灰色区域,如果AXD将第8行高亮就表示设置成功,然后选择【Execute】-> 【Run to Cursor】运行到光标,可以发现程序停止在第8行。 5.实验程序 AREA EXAMPLE1,CODE,READONLY ;声明代码段EXAMPLE1 ENTRY ;标识程序入口 CODE32 ;声明32位ARM指令 START MOV R0,#15 ;设置参数 MOV R1,#8 ; ADDS R0,R0,R1 ;R0=R0+R1 B START END

ARM嵌入式-ADS-1.2-集成开发环境练习实验报告

专业班级: 学号: 实验名称: 姓名: 实验所属课程: 实验室(中心): 指导教师: 实验完成时间:年月日

一、实验目的: 了解ADS 1.2 集成开发环境的使用方法。 二、实验设备: 1.硬件:PC 机一台 2.软件:Windows98/XP/2000 系统,ADS 1.2 集成开发环境 三、实验容: 1.建立一个新的工程; 2.建立一个C 源文件,并添加到工程中; 3.设置文本编辑器支持中文; 4.设置编译控制选项; 5.编译工程; 6.调试工程。 四、实验预习要求: 仔细阅读产品光盘附带文档《ADS 集成开发环境及仿真器应用》或其它相关资料,了解ADS 工程编辑的容。 五、实验步骤: 1. 启动ADS1.2 IDE 集成开发环境,选择【File】->【New…】,使用ARM Executable Image 工程模板建立一个工程,工程名称为ADS,见图 2.1。 图2.1 建立ARM 指令代码的工程

2.选择【File】->【New…】建立一个新的文件TEST1.S,设置直接添加到项目中,见图2.2。输入如程序清单2.1 所示的代码,并保存,见图2.3。 图2.2 新建文件TEST1.S 程序清单2.1 TEST1.S 文件代码 AREA Example1,CODE,READONLY ; 声明代码段Example1 ENTRY ; 标识程序入口 CODE32 ; 声明32 位ARM 指令START MOV R0,#15 ; 设置参数 MOV R1,#8 ADDS R0,R0,R1 ; R0 = R0 + R1 B START END 图2.3 添加了TEST1.S 的工程管理窗口

实验二 ARM环境下汇编语言实验

实验二ARM环境下汇编语言实验 一、实验目的 1、掌握基本的ARM汇编语言编程方法; 2、深入理解ARM开发环境的体系结构; 3、巩固使用AXD调试的方法 二、实验内容 1、单独使用ARM汇编语言编写一个工程,在AXD下调试,观察结果 三、实验设备 1、硬件:DM2410B+实验系统,PC机 2、软件:PC机操作系统(WINDOWS 2000),ARM Developer Suite v1.2 四、预备知识 1、掌握在ADS开发环境下建立工程与调试程序的方法(参考“ADS开发环境实验”与“JTAG 下载和调试实验”); 2、熟悉ARM汇编语言; 3、熟悉S3C2410芯片结构系统和实验系统的硬件资源(参考《DM2410实验系统使用手册》) 五、基础知识 ADS IDE开发坏境集成了CodeWarri or编译器和AXD Debugger调试器。在ADS IDE开发环境中编写的程序必须遵循CodeWarrior编译器所支持的语法规则 1、基于CodeWarrior的汇编语言语法及规则: 一个完整的汇编语句代码由3部分组成: 1)代码的行号:行号后面不用“:”结尾; 2)汇编指令或伪指令部分; 3)注释部分:以“;”开头 2、基于CodeWarrior的汇编语言伪操作 1) AREA伪指令 2)ENTRY伪指令 3)END伪指令 4)EQU指令 3、指令的条件域 当处理器工作在ARM状态时,几乎所有的指令均根据CPSR中条件码的状态和指令的条件域有条件的执行。当指令的执行条件满足时,指令被执行,否则指令被忽略。 每一条ARM指令包含4位的条件码,位于指令的最高4位[31:28]。条件码共有16种,每种条件码可用两个字符表示,这两个字符可以添加在指令助记符的后面和指令同时使用。 在1 6种条件标志码中,只有1 5种可以使用,第16种(1111)为系统保留,暂时不能使用。 4、存储器访问指令 ARM微处理器支持加载/存储指令用于在寄存器和存储器之间传送数据,加载指令用于将存储器中的数据传送到寄存器,存储指令则完成相反的操作。 常用的加载存储指令如下: ——LDR 字数据加载指令 ——LDRB 字节数据加载指令 ——LDRH 半字数据加载指令 ——STR 字数据存储指令 ——STRB 字节数据存储指令

1嵌入式系统实验环境介绍

《嵌入式系统》课程实验指导书 第一部分实验教学系统硬件介绍 第二部分Embest IDE集成开发环境使用说明 第三部分实验指导

第一部分实验教学系统硬件介绍 1.1教学系统的硬件电路 Embest S3CEV40开发板是实验系统的主要硬件平台,它是英蓓特公司开发的一款全功能ARM开发板,基于Samsung公司的S3C44B0X处理器(ARM7TDMI),资源丰富。硬件系统包含了嵌入式系统开发应用所需的大部分设备,如串口、以太网口、USB口、音频输出、LCD及TSP触摸屏、4*4的小键盘、固态硬盘、大容量的Flash和SDRAM等等。用户不仅可以在该硬件平台上完成实验系统提供的实验例子,还可以参考该平台设计自己的目标系统。 该硬件平台如下图所示: 图1-1 实验系统硬件平台 Embest S3CEV40开发板的基本资源如下: ●电源:外部5V电源供电或者由USB接PC供电,电源指示LED以及500mA保 险丝 ●1M×16bit Flash ●4×1M×16bit SDRAM ●4Kbit IIC BUS的串行EEPROM ●2个串口,其中一个为简单接口,一个为全接线接口,可跳接RS232 MODEM ●复位开关

●两个中断按钮,两个LED ●外部IDE硬盘接口 ●LCD及TSP触摸屏接口 ●20针JTAG接口 ●USB连接器 ●4×4键盘接口 ●4个2×20PIN CPU扩展接口 ●10M 以太网接口 ●8段数码管 ●MICROPHONE输入口 ●IIS音频信号输出口,可接双声道SPEAKER ●固态硬盘16M×8bit ●320*240 带触摸功能的显示屏 Embest ARM教学系统主要功能模块如图1-2 所示:

arm开发环境实验

ARM开发环境实验 实验目的 了解ADT IDE集成开发环境。 了解ADT IDE集成开发环境中基本的工程设置及程序编译方法。 掌握ADT IDE集成开发环境中基本的程序调试方法。 实验内容 熟悉ADT IDE集成开发环境。 建立一个基本的leddemo工程。 设置并编译leddemo工程。 调试leddemo工程。 基础知识: 本实验以leddemo程序为例,讲述在ADT IDE集成开发环境下,怎么编写、编译和调试程序。关于ADT IDE的更加详细的说明,可以参考ADT IDE用户手册。 1.连接调试器 本实验箱使用内置的简易调试模块,将计算机并口与实验箱简易JTAG接口通过并口延长线实现连接,并将JP5跳线通过跳线帽短接。 2.编辑编译调试。 建立工程。打开ADT IDE,选择菜单项File->New,弹出New对话框。 选择Project页,在Project页中选择调试设备。对于本实验箱使用简易调试器,选择ARM9SIMPLE。在Project name和Location编辑框中输入工程名称和路径,注意路径和工程名中不能包含空格。在Project type中选择EXEC。 新建一个文件并保存为d:\leddemo\leddemo.c,编辑该文件,添加如下代码: /***************************************************************** ***********/ /*文件名称:LEDSEG7.C */ /*实验现象:数码管依次显示出0、1,2、……9、a、b、C、d、E、F */ /***************************************************************** ***********/ #define U8 unsigned char unsigned char seg7table[16] = { /* 0 1 2 3 4 5 6 7*/ 0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, /* 8 9 A B C D E F*/ 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e, }; void Delay(int time);

嵌入式开发环境搭建

第一章开发环境搭建 要想进行嵌入式开发,首先,必须搭建一套完整的嵌入式开发环境。本章讲解在windows xp + Vmware虚拟机(安装Ubuntu10.04)环境下嵌入式开发环境的搭建。 1.1 交叉编译工具链的安装 嵌入式开发必须使用交叉编译工具链。你可以使用里仁提供的交叉编译工具(arm-linux-gcc-3.4.5和arm-linux-gcc-4.3.2),也可以使用crosstool-0.43或crosstool-ng自己编译交叉编译工具链。如何用工具自己编译交叉编译工具链,请参考其他资料。本节只讲解如何使用里仁提供的交叉编译工具链。 交叉编译工具链的安装步骤主要包括拷贝、解压和设置环境变量三部分。 1)拷贝 在主目录中建立工作目录liren,将交叉编译工具链拷贝到该目录下。 在/opt目录下建立virt.arm目录,将交叉编译工具解压到该目录下。操作时注意权限问题,需要加sudo执行命令。 其中,-C参数是制定解压后的存放目录。若不制定默认为当前目录。 查看/opt/virt.arm目录下的交叉编译工具。 arm-linux-gcc-3.4.5和arm-linux-gcc-4.3.2是两个版本的交叉编译器,以备以后使用。其中,arm-linux-gcc-3.4.5将在编译U-boot、文件系统及应用程序时使用;arm-linux-gcc-4.3.2将在编译内核时使用。 2)设置环境变量 把交叉编译工具解压到/opt/virt.arm目录后,编译程序时需要制定交叉编译工具的全路径。例如,在~/liren/test目录下编译“helloworld”。

不能够像gcc那样,直接使用arm-linux-gcc来编译,这是因为还没有设置环境变量。 在~/liren/sh/目录下创建两个脚本文件arm-linux-gcc-3.4.5.sh和arm-linux-gcc-4.3.2.sh。 分别为以下内容: arm-linux-gcc-3.4.5.sh arm-linux-gcc-4.3.2.sh 这两个脚本文件是用来设备环境变量的。 例如,执行source arm-linux-gcc-3.4.5.sh就会把交叉编译器arm-linux-gcc-3.4.5的路径加到PATH环境中。这样,就可以直接使用使用arm-linux-gcc编译程序了。 但是,用这种方法只能临时改变环境变量,退出终端后就失效,因此,在下次使用时需要重新设置。要想让设置长期生效,可以修改/etc/profile文件,在最后一行加上“export PATH=$PATH:/opt/virt.arm/arm-linux-gcc-x.x.x/bin”保存退出即可。不用重启系统,在终端运行“source /etc/profile”设置立即生效。 2.2 网络服务器的安装 在进行嵌入式开发时常常需要目标板和宿主机进行通信。因此,就会用到宿主机的网络服务。常用的网路服务有TFTP和NFS。下面介绍在Ubuntu10.04环境下安装TFTP和NFS 的方法。 2.2.1 安装配置TFTP服务 安装TFTP服务的步骤为: 安装tftp-hpa(客户端)和tftpd-hpa(服务器); 修改配置文件; 根据配置文件的路径,建立tftp目录,并修改目录权限; 重启tftp服务; 本地传输测试。

嵌入式Linux开发环境的建立实验报告

贵州大学实验报告 学院:计算机科学与信息专业:软件工程班级:软件091 姓名李鹏学号0908060150 实验组实验时间2011-11-28 指导教师薛现斌成绩实验项目名称嵌入式Linux开发环境的建立 对 P C 机的性能要求CPU:高于奔腾500M 内存:大于128M 硬盘:大于10G 实验步骤1. 安装REDHATLINUX 9.0 在一台PC安装REDHATLINUX 9.0 ,选择Custom定时安装,在选择软件package时将所有包都安装,选择everything,即安全安装。 2 . 开发环境配置 配置网络,包括配置IP地址、NFS服务、防火墙、网络配置只要是要安装好以太网卡。 使用RTL8139网卡,然后配置宿主机IP为192.168.0.121。如果是在多台计算机使用的局域网环境使用此开发设备,IP地址可以根据据具体情况设置。双击eth0d的蓝色区域,进入以太网设置界面。 对于REDHAT9.0,它默认防火墙是打开的,因此对于外来的IP访问它全部拒绝。因此,网络安装完毕后,应立即关闭防火墙。点击红帽子开始菜单,选择安全级别设置,选中无防火墙。 配置NFS:点击主菜单运行系统设置->服务器设置->NFS服务器,点击增加出现如下载界面,载目录(Drictory):中填入需要共享的路径,在主机(Hosts):中填入允许进行连接的主机。 3. 配置MINICOM (1)在linux操作系统Xwindow界面下建立终端,在终端的命令行提示符后输入minicom,回车,进入minicom的启动画面。 (2)minicom启动后,先按Ctrl+A键,再按Z键,进入主配置界面。按“O”进入配置界面。按上下键选择scrial port setup ,进入端口设置界面,选择你要的重要选项。

实验一 ARM嵌入式系统开发环境搭建

实验一ARM嵌入式系统开发环境搭建 一、虚拟机安装配置 ARM嵌入式系统开发需要linux环境,为了在windows下使用linux,需要安装虚拟机。虚拟机软件采用Virtualbox,linux操作系统的版本使用lubuntu。lubuntu系统已制成镜像文件,只需导入到virtulbox即可。 1. 安装VirtualBox虚拟机软件。采用默认安装。 2. 运行Virtualbox虚拟机软件,导入lubuntu虚拟机。 在“管理”菜单中,选择“导入虚拟电脑”项,在后续对话框中选择镜像文件,其余参数按照默认。 3. 启动lubuntu虚拟电脑进入linux界面。 二、建立交叉编译环境 1. 查看arm gcc 编译工具 # cd /opt/host/armv4l # ls bin 列出的以“armv4l-unkown –linux-”开头的系列文件就是gcc编译工具软件。 #armv4l-unknown-linux-gcc –v 应该显示以下信息:

如果没有出现该信息,则检查~/.bashrc文件,在其中加入“PATH=$PATH:$HOME/bin:/opt/host/armv4l/bin/”。 2. 建立桥接网络 当使用tftp下载程序时,为了使开发板能够访问虚拟机中的数据,需要对网络加以设置。开发板的IP为192.168.0.115;虚拟机的IP 设为:192.168.0.100 (1) 在lubuntu虚拟机的网卡配置中,选择“桥接网卡”, (2) 在windows操作系统网络配置界面中,将本地网卡和虚拟机的网卡桥接起来。桥接参数如下: IP设置为:192.168.0.2 掩码:255.255.255.0 网关:192.168.0.2 (3)lubuntu虚拟机的IP设置: 虚拟机IP:192.168.0.100 掩码:255.255.255.0 网关:192.168.0.2 3. 配置minicom参数 minicom程序用于在linux环境下通过串口和开发板通信。串口在烧写boot代码、操作系统内核及文件系统时使用。

北航ARM嵌入式系统实验 实验一 ARM基础知识和开发环境

实验一 ARM基础知识和开发环境 一、实验目的 1)掌握ARM的串行口工作原理。 2)学习编程实现ARM的UART通讯。 3)掌握S3C2410寄存器配置方法。 二、实验内容 1)熟悉打开已有工程的步骤,掌握仿真调试的方法。 2)建立一个新工程,熟练掌握编译器和链接器的设置方法。 3)从串口输入字符串,将0~9数字在超级终端上连续显示,“Enter”键换行。 4)将第三步得到的字符转换成BCD码,限制在0~1023,用于控制直流机。 三、设计方法 1)以实验一为模板,完成实验的1和2。 2)将接收串口数据的数组cl[1]改为cl[256],用cl[i]==0x0d 回车字符作为一帧结束的条件。 3)将“Exp4 电机转动控制实验”inc目录下的MotorCtrl.H 和src目录下的MotorCtrl.C拷到该工程相应目录,将MotorCtrl.C 添加到工程中。 4)在main函数里包含以下头文件#include “../inc/MotorCtrl.h”。 5)在main函数里包含以下头文件#include “inc/macro.h”,#define MOTOR_COUNT 12657 6)在Main函数里执行init_MotorPort( ); 7)直流电机调试的函数是SetPWM((setspeed-512)*MOTOR_COUNT/1024),setspeed是速度指令,取值范围0~1023. 四、预备知识 1)了解ADS集成开发环境的基本功能 2)学习串口通讯的基本知识 3)熟悉S3C2410串口有关的寄存器 五、实验设备

1)2410s教学实验箱 2)ARM ADS1.2集成开发环境 3)用于ARM920T的JTAG仿真器 4)串口连接线 六、实验原理及说明 1)异步串行通信 异步串行方式是将传输数据的每个字符一位接一位(例如先低位、后高位)地传送。数据的各不同位可以分时使用同一传输通道,因此串行I/O可以减少信号连线,最少用一对线即可进行。接收方对于同一根线上一连串的数字信号,首先要分割成位,再按位组成字符。 为了恢复发送的信息,双方必须协调工作。在微型计算机中大量使用异步串行I/O方式,双方使用各自的时钟信号,而且允许时钟频率有一定误差,因此实现较容易。但是由于每个字符都要独立确定起始和结束(即每个字符都要重新同步),字符和字符间还可能有长度不定的空闲时间,因此效率较低。 图1-1 串行通信字符格式 图1-1给出异步串行通信中一个字符的传送格式。开始前,线路处于空闲状态,送出连续“1”。传送开始时首先发一个“0”作为起始位(即双方同步信号),然后出现在通信线上的是字符的二进制编码数据。每个字符的数据位长可以约定为5位、6位、7位或8位,一般采用ASCII编码。后面是奇偶校验位,根据约定,用奇偶校验位将所传字符中为“1”的位数凑成奇数个或偶数个。也可以约定不要奇偶校验,这样就取消奇偶校验位。最后是表示停止位的“1”信号,这个停止位可以约定持续1位、1.5 位或2位的时间宽度。至此一个字符传送完毕,线路又进入空闲,持续为“1”。经过一段随机的时间后,下一个字符开始传送才又发出起始位。每一个数据位的宽度等于传送波特率的倒数。

嵌入式交叉开发环境的建立

实验四嵌入式交叉开发环境的建立 与通用计算机上的软件开发不同,嵌入式的编译过程被称为交叉编译,嵌入式系统的软件开发环境被称为嵌入式交叉开发环境。交叉编译就是把在宿主机上编写的高级语言程序编译成可以运行在目标机上的代码,即在宿主机上能够编译生成另一种CPU(嵌入式微处理器)上的二进制程序。交叉开发环境由宿主机和目标机组成,宿主机与目标机之间在物理连接的基础上建立起逻辑连接。 宿主机(Host)是用于开发嵌入式系统的计算机。一般为PC机(或者工作站),具备丰富的软硬件资源,为嵌入式软件的开发提供全过程支持。目标机(Target)即所开发的嵌入式系统,是嵌入式软件的运行环境,其硬件软件是为特定应用定制的。物理连

接是指宿主机与目标机通过物理线路连接在一起,连接方式主要有串口、以太网接口和OCD(On Chip Debug)三种方式。逻辑连接指宿主机与目标机间按某种通信协议建立起来的通信连接。在开发过程中,目标机端需接收和执行宿主机发出的各种命令如设置断点、读内存、写内存等,将结果返回给宿主机,配合宿主机各方面的工作。 宿主机上用于嵌入式软件开发的工具软件一般包括:文本编辑器、交叉编译器、交叉调试器、仿真器、下载器等。 当我们建立完成了嵌入式交叉开发环境后,我们就可以按照如图1所示,在宿主机上编写程序的源代码,使用交叉编译器编译成各个目标模块,使用交叉链接器链接生成可供下载调试或固化的目标程序,通过目标机和宿主机之间的物理连接(串口或网络接口)

将目标程序下载到目标机。 图1嵌入式软件编译过程 在这里中,我们是在宿主机的虚拟机(VMware Workstaion 6.5)上安装Red Hat Enterprise Linux 5。在Linux环境下,我们一般采用arm-linux-gcc作为交叉编译器,glibc是应用程序编程的函数库文件软件包,binutils用作二进制程序处理工具。这样一些软件构成了Linux下的交叉编译工具链。 通常构建交叉工具链有3种方法: (1)分步编译和安装交叉编译工具链所需要的库和源代码,最终生成交叉编译工具链;

相关主题
文本预览
相关文档 最新文档