第1个ARM裸板程序及引申(第004节_汇编与机器码)【修改机器码点亮led2]
汇编代码如下,点亮 jz2440 LED1 灯
/** 点亮LED2: gpf5*/.text
.global _start_start:/* 配置GPF5为输出引脚* 把0x400写到地址0x56000050*/ldr r1, =0x56000050ldr r0, =0x100 /* mov r0, #0x400 */str r0, [r1]/* 设置GPF5输出高电平 * 把0写到地址0x56000054*/ldr r1, =0x56000054ldr r0, =0 /* mov r0, #0 */str r0, [r1]/* 死循环 while(true) 相当于 */
halt:b halt
反汇编以后的代码: 上面代码存在伪指令 伪指令转化为在真正 汇编指令
Makefile
all:arm-linux-gcc -c -o led_on.o led_on.Sarm-linux-ld -Ttext 0 led_on.o -o led_on.elfarm-linux-objcopy -O binary -S led_on.elf led_on.binarm-linux-objdump -D led_on.elf > led.on.dis # 反汇编
clean:rm *.bin *.o *.elf
最终生成的: led.on.dis
led_on.elf: file format elf32-littlearmDisassembly of section .text:伪指令转化为在真正 汇编指令 地址:可以理解为序号,地址在sram定义真正的
地址 机器码 汇编码 00000000 <_start>:0: e59f1014 ldr r1, [pc, #20] ; 1c <halt+0x4>4: e3a00c01 mov r0, #256 ; 0x1008: e5810000 str r0, [r1]c: e59f100c ldr r1, [pc, #12] ; 20 <halt+0x8>10: e3a00000 mov r0, #0 ; 0x014: e5810000 str r0, [r1]00000018 <halt>:18: eafffffe b 18 <halt>1c: 56000050 .word 0x5600005020: 56000054 .word 0x56000054
Disassembly of section .ARM.attributes:00000000 <.ARM.attributes>:0: 00001741 andeq r1, r0, r1, asr #144: 61656100 cmnvs r5, r0, lsl #28: 01006962 tsteq r0, r2, ror #18c: 0000000d andeq r0, r0, sp10: 00543405 subseq r3, r4, r5, lsl #814: 01080206 tsteq r8, r6, lsl #4
地址是nand上的地址 ,cpu 从0地址上读取依次读取机器码,会把所有的机器码loading到内存里面去, 程序运行内存上的机器码
上面代码解读 :
arm 有32个寄存器, r0-r16,
pc : 程序指针 当前地址 +8 , 为什么, pc = 当期地址+8 , 在执行0时候,已经在解析4,读取8在 [这个叫做 汇编的流水线]
pc : 程序寄存器, 当前程序执行在哪里, 所以只有一个,一个国家只有一个皇帝 , pc 指向那条指令, cpu执行哪条 , 程序跑飞了, pc寄存器内容不对了
sp : 栈指针
lr : 包含返回地址, 函数执行完毕要回到原来地方,原来地方就是保持在lr里面
arm 内部的寄存器 + 别名
解析第一条指令 : 0: e59f1014 ldr r1, [pc, #20] ; 1c <halt+0x4> (这就是伪指令的实际汇编)
当前指令地址是0 , pc = 0 + 8 + 20 = 0x1c 去0x1c 读取该地址的值56000050 写入 r1
1c: 56000050 .word 0x56000050
0:表示当前地址 8可以理解为流水 执行当前执行,实际读取往后读取到8地址, 20就是#20
【这里可以这么理解: pc首先指向0,执行该指令, 然后执行0x1c读取寄存器 pc指了2个方法】
第二条: mov r0, #5376 ; 0x1500 把 0x1500 写入 r0 【pc继续往下走,执行第二条】
第三条: e5810000 str r0, [r1] 把 r0 0x1500 写入到 r1 对应内存
第四条: c: e59f100c ldr r1, [pc, #12] ; 20 <halt+0x8>
0xc 【当前指令的地址】+ 8 + 20 = 0x20 去0x20地址读取它的值0x056000054存放到 r1中 r1=0x56000054(cpu把寄存器单做内存来使用)
.....
编译器 把 伪指令转化为在真正 汇编指令
把汇编指令转化为机器码, led.bin内部就是机器码
机器码就是可以烧写到裸机上
汇编码、C都是给程序员一样看的,机器码给机器跑的
在上面基础上要实现功能:
练习: 在 原来编译的 led_on.S 修改 机器码, 点亮 LED2
那么需要去修改机器码, 如何修改机器码 , 就要知道 上面的第二条 mov 指令
这内部是如何转化的 汇编码和机器码
4: e3a00c15 mov 《============》 r0, #5376 ; 0x1500
看芯片手册: ARM Architecture Reference Manual 找到mov 指令
上图解读:
bit[23-20] 1010 表示mov指令
bit[15-12] 0000 表示r0
bit[11-0] 表示0x100
修改机器码, mov r0,#0x400 那么就可以点亮led2了, 如果是汇编,那么如何修改机器码直接
bit[11-0] 12位如何表示 0x100 研究?
分析 :
整个12 位: 高4位 (rotate) + 低8位 (immed_8) = 12
立即数
低8位运算:
高4位运算:
例子:
0x100 二进制 0001 00000000 立即数 1100 0000 0001 如何运算来的
如何运算得到立即数的:
一共32位,1要通过右移编程 ... 0001 ,1 右移24位
ratate = 24/2 = 12 1100 所以立即数就是: 1100 0000 0001
同理要点亮led2:
0x400 而进制 0100 00000000
低8位: 1左移动22位 ---- 0000 0001
高8位: 22/2= 1 ---- 1011
立即数: 1011 0000 0001
用UE打开led.bin,修改地址 e3a00c01 为 e3a00cb1烧进去 ,那么就可以点亮led2了
0x100是不是 1循环右移 24位 ? 这里以32位为准,
00000....000000000000000(23个0)1 右移动24位就是 00-00(23位)100000000(8个0) 23+1+8=32
那么我们把 :
12位: 高4位 (rotate,移位数) + 低8位 (immed_8 立即数,循环右移动2*rotate位)
rotate = 12 immed_8 = 1
-比如: 0x100 立即数: 1100 00000001
如果我们要点亮第二个LED灯: 此时 ldr r0, =0x400 /* mov r0, #0x400 */
0x400 1右移动 22位 0000...00(21个0)10000....0(10个0)
rotate = 22/2=11 1011
immed_8 = 1 0000 0001
修改: bit[11-0] 其他的不变, 在LED的基础上
修改led.bin
刷进去点亮的是led2
资源地址:修改机器码点亮led2-资料2021-11-21.zip-Unix文档类资源-CSDN下载
第1个ARM裸板程序及引申(第004节_汇编与机器码)【修改机器码点亮led2]相关推荐
- 关于在arm裸板编程时使用printf问题的解决方法
在ARM裸板驱动编程中,是不允许程序直接调用C库程序的.为什么呢?因为此时kernel还没有被加载,所以在封装在kernel层的C库的API是用不了的,那怎么办? 在开发过程中,printf的功能我不 ...
- tiny4412裸板程序之点灯(一)
最近折腾tiny4412开发板,先用裸板点个灯,玩一下裸板程序,后面打算移植最新的uboot和内核到tiny4412开发板上去. 原理图中,4个led用到的是GPM4_0 - GPM4_4. 看芯片手 ...
- 【嵌入式开发】LED 驱动 ( LED发光二极管原理 | 底板原理图分析 | 核心板原理图分析 | GPIO | 裸板程序烧写流程 )
文章目录 开发板 的 LED 灯 作用 : 嵌入式软件的开发初期, 如 开发 BootLoader 代码 或者 Kernel 内核代码 过程中, 有效的调试方法有限, 此时通常使用 开发板上的 LED ...
- TQ210——TFTP裸板程序下载
TQ210--TFTP裸板程序下载 1. 直接下载u-boot.bin到内存运行(使用DNW中的的210USB启动下载),在DNW中输入命令可以直接查看修改u-boot.bin 2. 通过tftp下载 ...
- 第0课第2节_刚接触开发板之烧写裸板程序
第0课第2节_刚接触开发板之烧写裸板程序 tftp用法 q //退出菜单 help tftp print //显示IP set ipaddr 192.168.31.203 //设置开发板IP set ...
- 2021-10-18使用eop烧写裸板程序
安装串口驱动 使用串口软件MobaXterm->点Session->找到串口->选择串口->设置波特率115200->点击Advanced Serial setting- ...
- 使用eop烧写裸板程序步骤
初次使用eop烧写裸板程序步骤 1.eop连接到PC. 2.安装驱动(若安装失败,则需要禁用驱动签名即可,步骤看我之前发布的文章). 3.安装App. 4.开发板连接eop,eop连接PC. 5.执行 ...
- Qtcreator远程调试arm开发板程序指南
环境配置 1 ,交叉编译gdb, 主要是gdbserver,把gdbserver 放在arm开发板的可执行程序目录里 2 安装gdb-multiarch, sudo apt-get install g ...
- 在riscv sifive u740开发板上运行FreeRTOS及裸板程序
riscv是当前比较火热的玩意,sifive的u740开发板是当前性能还不错的板子. sifive官方提供了一个SDK,https://github.com/sifive/freedom-e-sdk ...
最新文章
- python常用模块大全总结-python常用模块整理
- linux命令总结之traceroute命令
- 一篇文章看懂Git是什么以及如何简单的上手Git
- [渝粤教育] 西南科技大学 动态网页设计(JSP) 在线考试复习资料
- java 不加锁_在java中,在高并发的时候,不加锁的时候。
- opencv python安装_Python 安装 第三方库的安装技巧
- asp.net使用httpModule来实现一个反向代理
- linux reboot故障
- Python 2和Python 3 用pip 安装时如何区分
- 上海怎样查询最近三年社保明细
- java输入两个数字和运算符_java 第二天运算符及录入函数Scanner
- 访问weblogic控制台报错的问题处理
- 数据库基础之位图索引
- 【排序】快排(霍尔快排)
- windows PCIe 工具: TeleScan
- 如何配置nginx,实现在手机上查看页面?
- zigbee 问题一:协调器究竟如何选择信道?
- H5 直播的疯狂点赞动画如何通过php直播平台源码实现(附完整源码)
- 【车位检测】基于计算机视觉实现停车场空位识别附matlab代码
- 微信 for BlackBerry
热门文章
- 远程计算机网络怎么设置,vpn错误720:不能建立到远程计算机的连接。你可能需要更改此连接的网络设置...
- Leetcode042接雨水039直方图最大矩形面积
- XFTP与XSHELL系统错误,缺少MSVCP110.DLL与MSVCR110.DLL解决办法
- html做万用表效果,牛人DIY高精度六位半数字万用表 - 电子制作 - 电子发烧友网...
- 手机游戏地图绘制软件
- 微信公众平台开发视频上传
- 【C#】RGB转CMYK
- windows 10安装sqlyog详细步骤
- 漫画 |《帝都老板十二时辰》
- 国际护士节活动策划PPT模板