ARM基础编程实验
目录
1.熟悉并掌握常用ARM汇编指令2.熟悉并掌握“C+汇编”混合编程技术3.熟练使用ARM软件开发调试工具Keil
1.学习使用Keil开发工具2.实现累加运算功能
3.实现字符串拷贝功能4.实现求和运算功能
5.实现冒泡排序算法
实验1.1:运行Keil,建立工程文件,单步运行调试演示示例程序,深刻理解每一条指令,观察寄存器,内存空间的变化。
此处提供六个示例实验:
其中ARM数据处理指令寻址方式实验和ARM内存访问指令寻址方式实验为必做实验。
ARM堆栈指针寄存器实验、ARM程序计数器实验、ARM程序状态寄存器实验、ARM工作模式切换实验为选做部分,鼓励大家利用课上剩余时间或课后完成此部分内容。
Keil的具体使用步骤如下:
1.点击“Keil uVision5”打开软件主窗口。
2.点击Project->New uVision Project建立新工程。
3.为新工程命名。
4.为工程选择目标器件:三星S3C2440A。
5.选择是否添加S3C2440.s启动文件:C源程序工程选“是”,汇编源程序工程选“否”。
6.在工程Source Group上点右键选择添加新工程文件。
7.选择源文件类型。
8.录入源代码并保存。
9.对工程进行build或rebuild。
10.点击debug按钮进入/退出调试,忽略代码大小限制。使用单步调试,仔细观察过程中关键寄存器值的变化。
实验1.2:用ARM汇编实现1+2+…+N的累加运算
1.将实验1.2文件夹中的sum.s文件添加至工程中。
2.在文件中,用汇编实现算法核心部分,需添加的代码参考流程图如下:
3. 运行Debug进行调试。
实验1.3:理解C和汇编,并用汇编程序实现字符串拷贝,并在C程序中调用该汇编程序。
1.将实验1.3文件夹中的testfile.s和main.c文件添加至工程中。
2.在汇编文件testfile.s中添加两行汇编代码,分别实现:
1) 拷贝源字符串的一个字节到R2中;
2) 将拷贝的字节复制到目标空间。
3.运行Debug进行调试。
实验1.4:在汇编中调用C函数。
1.将实验1.4文件夹中的sum.c和testfile.s文件添加至工程中。
2.在汇编文件testfile.s中相应位置添加汇编代码,通过调用c函数g()实现1+2+3+glovb1,结果存在R8中。
3.运行Debug进行调试,观察实验现象。
实验1.5:用ARM汇编实现冒泡算法。(选做)
1.将实验1.5文件夹中的maopao.s文件添加至工程中。
2.在汇编文件maopao.s中相应位置添加汇编代码,实现冒泡排序。
3.运行Debug进行调试。
4.在debug界面,点击Debug →Memory Map,修改地址分段属性。
5.观察实验现象
| 1.1实验一 |
| ARM数据处理指令寻址方式
ARM内存访问指令寻址方式实验
ARM堆栈指针寄存器实验
ARM程序计数器实验
ARM程序状态寄存器实验
ARM工作模式切换实验
|
| 1.2实验部分关键代码: |
| ADD R0,R1 BVS SUM_END CMP R1,R2 BHS SUM_END ADD R1,#1 B SUN_L1 |
| 1.2实验结果: |
|
可以看到,R0和R8中的值为13BA,符合1+2+…+100的实验结果
|
| 1.3实验部分关键代码: |
| LDRB R2,[R1],#1 ;拷贝源字符串的一个字节 STRB R2,[R0],#1 ;将拷贝的字节复制到目标空间
CMP R2,#0 BNE strcopy
MOV PC,LR ;------------------------------------------
END ;文件结束
|
| 1.3实验结果: |
|
字符串变量由’bbbb’拷贝为’aaaa’
|
| 1.4实验部分关键代码: |
| MOV R0,#1; MOV R1,#2; MOV R2,#3; MOV R3,#10; BL g MOV R8,R0; |
| 1.4实验结果: |
|
可以看到R0中的值再相加之后变为了0x10,结果为16,符合实验的预期。
|
| 1.5冒泡排序实验部分关键代码: |
| LDR R2,[R1] LDR R3,[R1,#4] CMP R2,R3 STRGT R3,[R1] STRGT R2,[R1,#4] ADD R1,R1,#4 CMP R1,R6 BLT inner
ADD R4,R4,#4 CMP R4,#len SUBLE R6,R6,#4 BLE outer |
| 1.5实验结果: |
|
|
1.此次实验用汇编和C语言实现了1~N的累加、字符串的拷贝、数字求和以及冒泡法排序这几项功能,了解了汇编语言的基础指令及其意义,同时初步入门了Keil编译器的使用与程序编写调试。
2.知道了C程序与汇编语言相互调用的规则:
a)寄存器的使用规则:“子程序间”通过寄存器R0~R3来传递参数。在“子程序中”,使用寄存器R4~R11来保存局部变量。
b)寄存器R12用于子程序间scratch寄存器(用于保存SP,在函数返回时使用该寄存器出桟),记作IP。
c)寄存器R13用于数据栈指针,记作SP。寄存器SP在进入子程序时的值和退出子程序时的值必须相等。
d)寄存器R14称为链接寄存器,记作LR。它用于保存子程序的返回地址。
e)寄存器R15是程序计数器,记作PC。
1、ADD替换成ADDS ,SUB替换成SUBS有什么影响?替换后,运算结果会影响标志寄存器。因为ADD、SUB不带进位与借位,ADDS、SUBS带有进位与借位,运算完成要置符号位。
2、MOV替换成MOVNE有什么影响?替换后只有在上一步计较结果为不相等的时候才会执行该指令。
3、STMIA换成STMIB ,STMIA换成STMDA有什么区别?换成STMIB是将每次传送后的地址+4变成每次传送前地址+4,换成STMDA是将每次传送后的地址+4变成每次传送后地址-4。
4、思考用ARM汇编实现1+3+5+….+(2n+1)或者2+4+6+…..+2n。实现前者,将ADD R1,#1改为ADD R1,#2,并设置R1初始值为1。
实现后者,将ADD R1,#1改为ADD R2,#2,设置R1初始值为2。
5、实验3中如果去除汇编代码中的“EXPORT strcopy”会有什么现象,为什么?若去除汇编代码中的‘EXPORT strcopy’,则在C语言里面无法调用该函数,因为EXPORT用于声明strcopy为全局标号。
6、实验4中如果去除汇编代码中的“IMPORT …..” 会有什么现象,为什么?
会无法调用C语言的main函数,因为该伪指令用于通知编译器要使用的标号或者变量在其他的源文件定义。
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
我想用这两种语言中的任何一种(最好是ruby)制作一个窗口管理器。老实说,除了我需要加载某种X模块外,我不知道从哪里开始。因此,如果有人有线索,如果您能指出正确的方向,那就太好了。谢谢 最佳答案 XCB,X的下一代API使用XML格式定义X协议(protocol),并使用脚本生成特定语言绑定(bind)。它在概念上与SWIG类似,只是它描述的不是CAPI,而是X协议(protocol)。目前,C和Python存在绑定(bind)。理论上,Ruby端口只是编写一个从XML协议(protocol)定义语言到Ruby的翻译器的问题。生
我对图像处理完全陌生。我对JPEG内部是什么以及它是如何工作一无所知。我想知道,是否可以在某处找到执行以下简单操作的ruby代码:打开jpeg文件。遍历每个像素并将其颜色设置为fx绿色。将结果写入另一个文件。我对如何使用ruby-vips库实现这一点特别感兴趣https://github.com/ender672/ruby-vips我的目标-学习如何使用ruby-vips执行基本的图像处理操作(Gamma校正、亮度、色调……)任何指向比“helloworld”更复杂的工作示例的链接——比如ruby-vips的github页面上的链接,我们将不胜感激!如果有ruby-
我有一个super简单的脚本,它几乎包含了FayeWebSocketGitHub页面上用于处理关闭连接的内容:ws=Faye::WebSocket::Client.new(url,nil,:headers=>headers)ws.on:opendo|event|p[:open]#sendpingcommand#sendtestcommand#ws.send({command:'test'}.to_json)endws.on:messagedo|event|#hereistheentrypointfordatacomingfromtheserver.pJSON.parse(event.d
我正在尝试解析网页,但有时会收到404错误。这是我用来获取网页的代码:result=Net::HTTP::getURI.parse(URI.escape(url))如何测试result是否为404错误代码? 最佳答案 像这样重写你的代码:uri=URI.parse(url)result=Net::HTTP.start(uri.host,uri.port){|http|http.get(uri.path)}putsresult.codeputsresult.body这将打印状态码和正文。
我想验证一个电子邮件地址是否是PayPal用户。是否有API调用来执行此操作?是否有执行此操作的ruby库?谢谢 最佳答案 GetVerifiedStatus来自PayPal'sAdaptiveAccounts平台会为您做这件事。PayPal没有任何codesamples或SDKs用于Ruby中的自适应帐户,但我确实找到了编写codeforGetVerifiedStatusinRuby的人.您需要更改该代码以检查他们拥有的帐户类型的唯一更改是更改if@xml['accountStatus']!=nilaccount_status
我想知道我应该如何着手这个项目。我需要每周向人们发送一次电子邮件。但是,这必须在每周的特定时间自动生成并发送。编码有多难?我需要知道是否有任何书籍可以提供帮助,或者你们中的任何人是否可以指导我。它必须使用rubyonrails进行编程。因此有一个网络服务和数据库集成。干杯 最佳答案 为什么这么复杂?您只需安排工作。您可以使用Delayed::Job例如。Delayed::Job让您可以使用run_at符号在特定时间安排作业,如下所示:Delayed::Job.enqueue(SendEmailJob.new(...),:run_
我查看了Stripedocumentationonerrors,但我仍然无法正确处理/重定向这些错误。基本上无论发生什么,我都希望他们返回到edit操作(通过edit_profile_path)并向他们显示一条消息(无论成功与否)。我在edit操作上有一个表单,它可以POST到update操作。使用有效的信用卡可以正常工作(费用在Stripe仪表板中)。我正在使用Stripe.js。classExtrasController5000,#amountincents:currency=>"usd",:card=>token,:description=>current_user.email)
当profile为nil时,总是让我感到悲伤...我该怎么办? 最佳答案 在View中使用变量之前,始终检查变量是否为nil。我确信这个问题有更优雅的解决方案,但这应该能让您入门。 关于ruby-on-rails-Rails处理.Erb与Nils,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/2709605/
我有一个应用程序专门使用Facebook作为身份验证提供程序,并正确设置了生产模式的回调。为了让它工作,您需要为您的Facebook应用程序提供一个站点URL和一个用于回调的站点域,在我的例子中是http://appname.heroku.com和appname。heroku.com分别。问题是我的Controller设置为只允许经过身份验证的session,所以我无法在开发模式下查看我的应用程序,因为Facebook应用程序的域显然没有设置为本地主机。如何在不更改Facebook设置的情况下解决这个问题? 最佳答案 创建另一个域l