摘要:
第一篇csdn日志,记录今天为了学习汇编而配置开发环境的过程,解决了一些疑问点和坑,上传以供分享、学习、交流。
两种模拟环境配置方式:
1、Qemu 模拟器:
为方便C开发编程,在Ubuntu 12.04LTS下安装qemu模拟器来模拟arm开发环境:
sudo apt-get install qemu qemu-system
测试安装结果:
qemu-system-arm -version
在12.04Lts版本下,安装的是qemu1.0.50版本,编译执行链接过程顺利执行过后,汇编测试结果正常。
在16.04Lts版本下,安装的是qemu2.5.0版本,编译执行链接过程顺利执行过后,汇编测试结果异常,主要现象是汇编的STR 指令失效:
str r0,[r1] //r0中的数值并没有存储到r1存储的地址空间中
原因可能是qemu和新的ubuntu版本之间不兼容(具体详细原因不明)。
2、keil(mdk):
相关工具:
交叉编译工具链 arm-2011.09-70-arm-none-linux-gnueabi -- 针对ARM的编译源码的工具
keil(mdk) -- 用于源码编辑、调试的工具。
配置步骤:
- 安装交叉编译工具链
- 安装Keil(mdk)开发工具,注意packs的路径
- 官网 http://www.keil.com/dd2/ 下载 离线支持包并安装
- 官网 http://www2.keil.com/mdk5/legacy 下载Legacy device database(旧设备数据库)
- 创建新的uVision工程,新建空白文件(start.s),编辑汇编代码,作为已存在文件添加进当前Group
- 选中当前Target,打开管理项目对话框,勾选Use Gcc,并设置prefix(- 易漏)和Folder(推荐打开交叉编译文件根目录并复制粘贴目录)
- 拷贝map.lds链接脚本到当前test01.uvprojx文件目录下,打开Options for target对话框选中linker选项卡,设置linker script file为test目录下的map.lds
- (易漏)选择Debug选项卡中的Use Simulator模式。
tips:
1、编译出错 - 非常迷的一点,设置GCC编译后,rebuild提示错误
--- Error: failed to execute 'arm-none-linux-gnueabi-gcc'
然后切换为ARMCC后,rebulid正常报错;错了就换回来吧,等重新又选择GCC编译并编译运行后,0 error,0 waring。
keil真的无话可说,活脱脱花了二十分钟排错。
2、调试出错 - 开始debug的时候,内存起始地址0x00000000以后的指令都是
addeq r0,r0,r0
而点击跳转到start.s的第一条指令,在像0x000008ef左右的地址上,非常奇怪。
回顾检查前面的操作,编译成功的条件下,原来链接脚本设置那块默认又清空了
就是这个地方,清空了,按照正常步骤添加回去就好了,然后重新debug,发现start.s文件第一条指令就在0x00000000
3、如果调试出现*** error 65: access violation at C:0xFFA7 : no 'execute/read' permission,大概率是地址设置出错了,查看lds链接脚本或Linker scrpit设置大概率能解决这个问题。如果不行,就试试debug模式下的地址映射吧。再不济,检查下Options中的Debug下dll的设置,应该能解决(不能解决又能怎样呢?笑~)
4、keil的错误: Error: Encountered an improper argument
遇到第四个错误真的是瑟瑟发抖,算是最后的BOSS了吧。弹窗提示关不完,资源管理器把keil5进程杀了,重新打开就可以了。网上说是设置的断点没清理干净,大概率是这样的,算是keil新版本的BUG吧。
为什么这么说?因为在测试过程中,设置了断点同样遇到这个问题,不过干脆就kill了进程重启,没有太深刻的印象了。
最后:
综上流程和问题都处理清楚后,编译的汇编程序在debug下正常完美地跑起来。中途无数次,从疑惑到崩溃,从崩溃到一线希望,随后再崩溃,再蒙圈,感觉成功就是那么0.01的概率,keil你告诉我,我跑起来是不是在你的预料之外,天知道运行顺利是不是keil的BUG呢。
开个玩笑,小心翼翼地调试检测,明白其中原理,就会好很多了,加油吧优衣酱,go!!
最后的最后,补上lds模板,希望有人能用到(这里是地球。不要回答,不要回答!)
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") /* 指定输出的文件格式 */
OUTPUT_ARCH(arm) /* 生成文件支持arm系列的CPU */
ENTRY(_start) /* 连接后的第一条指令所在的地址是_start */
SECTIONS /* 目标文件的摆放 */
{
. = 0x00; /* 指定链接的起始地址 */
. = ALIGN(4); /* 指令的对齐 */
.text : /* 代码段的开始 */
{
start.o(.text) /* start.o文件放在开始的位置 */
*(.text) /* 其他目标文件自动分配位置 */
}
. = ALIGN(4); /* 代码的对齐*/
.data :
{ *(.data) }
. = ALIGN(4);
.bss :
{ *(.bss) }
}