今天在晚上找到一个简单的ARM64在线仿真器,它非常适合学习ARM64的指令,在教学中应该很好用。网址ARM64 Online Simulatorhttp://163.238.35.161/~zhangs/arm64simulator/
它是由康涅狄格州立大学的Shuqun Zhang教授开发的。软件基于Alexandro Sanchez开发的Unicorn CPU emulator framework for JavaScript (https://github.com/AlexAltea/unicorn.js)。这是一个非常有名的轻量级CPU仿真器。
我们使用一个简单的斐波那契数列计算程序进行了测试:
main:
mov x0, 10
mov x1, #1
mov x2, #1
mov x3, #0
START:
cmp x0, x1
b.gt LOOP
b.eq END
LOOP:
add x4, x2, x3
mov x3, x2
mov x2, x4
add x1, x1, #1
b START
END:
mov x0, x4
这段ARM汇编程序是一个简单的循环计算程序。下面是对每行代码的解释:
mov x0, 10
: 将寄存器x0的值设置为10。这通常用作循环计数器。mov x1, #1
: 将立即数1移动到寄存器x1,用作循环的初始值。mov x2, #1
: 将立即数1移动到寄存器x2,用作循环的起始值。mov x3, #0
: 将立即数0移动到寄存器x3,用作循环中的累加器。
接下来是程序的主要部分:
-
START:
: 标签,标记循环开始的地方。 -
cmp x0, x1
: 比较寄存器x0和x1的值。 -
b.gt LOOP
: 如果x0大于x1(即循环计数器x0大于1),则跳转到标签LOOP
。 -
b.eq END
: 如果x0等于x1,跳转到标签END
,结束程序。 -
LOOP:
: 标签,标记循环体开始的地方。 -
add x4, x2, x3
: 将x2和x3的值相加,结果存储在x4中。这是计算斐波那契数列的步骤。 -
mov x3, x2
: 将x2的值移动到x3,为下一次迭代准备前一个斐波那契数。 -
mov x2, x4
: 将x4的值移动到x2,更新当前的斐波那契数。 -
add x1, x1, #1
: 将x1的值增加1,这是循环计数器的更新。 -
b START
: 无条件跳转到START
标签,继续循环。 -
END:
: 标签,标记程序结束的地方。 -
mov x0, x4
: 将x4的值移动到x0,这通常是程序的返回值或最终结果。
这个程序计算的是斐波那契数列的第10项(因为初始时x0为10)。斐波那契数列是这样的序列:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ...,其中每一项都是前两项的和。
运行结果:
- 初始时x2和x3都是1(斐波那契数列的前两项)。
- 经过9次循环(因为x0从10递减到1),x4将包含斐波那契数列的第10项的值。
根据斐波那契数列的定义,第10项的值是55。因此,程序运行结束后,寄存器x0将包含值55。
将程序输入到仿真器中,然后运行程序就可以得到正确的结果。
仿真器的主要功能:
- 支持64位ARM指令集。4千字节内存(地址范围0x10000 - 0x11000)。
- 代码段:0x10000 - 0x107FF,数据段:0x10800 - 0x10DFF,栈段:0x10E00 - 0x10FFF
- 不支持:伪指令(directives),系统调用(SVC)
- 伪指令 "LDR reg, #imm" 不被支持。您可以使用 "ADR x1, #0x800" (寄存器x1将具有0x10800的值而不是0x00800),然后使用 "LDR/STR x2, [x1]" 来加载/存储数据段中的数据。
- 您可以通过双击寄存器,并输入新的十六进制值来修改寄存器的值。