我想模拟ARM代码。例如,我想运行这样的代码:
MOV R0, #5
ADD R0, R0, #1
//somehow output R0
它会在我的 Ubuntu 上的某些软件上输出 6。是否可以?
Keil MDK可用于模拟 ARM 代码。它提供了一个Simulate/Debug透视图,可用于探测 ARM 寄存器集、内存内容等……
MDK-Lite 评估版免费提供,最大代码大小为 32KB。
Linux 版本的 MDK 不可用。但是 Keil MDK在 Ubuntu 中可以在WINE上完美运行。
第 1 步:在 Ubuntu 上安装 wine
打开终端并输入:
sudo apt-get install wine
第 2 步:下载Keil MDK。
第 3 步:安装 MDK
右键单击MDK可执行文件并选择“使用 Wine Windows 程序加载器打开”选项。
第 4 步:在 Ubuntu 上调用 Keil uVision MDK
打开终端并输入:
wine ~/.wine/drive_c/Keil/UV4/Uv4.exe
第 5 步:安装 Flash Magic(可选)
Flash Magic 是一款用于下载 Keil 板卡软件的工具。下载Flash Magic 软件并将其安装在 wine 上(参考前面的步骤)。
创建到串行端口的 COM1 链接。打开终端并输入:
ln -s /dev/ttyS0 ~/.wine/dosdevices/COM1
第 1 步:为 ARM7 目标创建 Keil UVision 项目。
在 Keil UVision 工具栏中选择Project --> New Project。
导航到要创建此项目的位置。
输入项目名称并单击Save。
选择ARM --> ARM7(Little Endian)作为 Target 的设备。单击确定。
第 2 步:为目标创建程序集源文件
在 Keil UVision 工具栏中选择File --> New。将以下代码添加到新创建的文件中:
AREA text, code, readonly
ENTRY
MOV R0, #5
ADD R0, R0, #1
END
如上所述,在每个汇编语句之前提供制表符空间。使用“.s”扩展名保存文件。
第 3 步:将源文件添加到项目中
在项目窗口(位于 UVision 左侧)中,右键单击Source Group 1并选择“ Add Files to Group Source Group 1 ”选项。
选择test.s并点击'Add'。(选择文件类型作为ASM 源文件)
第 4 步:构建源文件
在 Keil UVision 工具栏中选择Project --> Build target或按F7编译源文件。
第 5 步:模拟/调试应用程序
在 Keil UVision 工具栏中选择Debug--> Start/Stop Debug Session或按Ctrl + F5。
调试透视图打开,左侧有一个寄存器视图,中间有代码视图,右下角有内存视图,等等......
使用调试键执行代码:
在程序执行结束时观察寄存器视图:
在 Keil UVision 工具栏中选择Debug--> Start/Stop Debug Session或按Ctrl + F5退出 Debugging Perspective。
如果你将它构建成一个实际的可执行文件,那么你可以使用QEMU的 ARM 模拟器来运行它。
您可以通过作为模拟器的 QEMU 运行 arm 代码,但我认为您不能直接输出到另一个软件,因为 QEMU 也是一个软件,但您可以使用共享内存甚至文件之类的东西(警告并发访问文件可能需要互斥体)将结果从模拟器传递到主机软件并返回,即使它可能有点慢
本文逐步介绍了使用 QEMU 模拟裸机 ARM 代码: http ://balau82.wordpress.com/2010/02/28/hello-world-for-bare-metal-arm-using-qemu/
当然你不需要照顾 C 的东西,可以直接将你的程序集放在 startup.s
我想您所追求的是一种printf
从 C 程序获取 ARM 汇编函数返回值的方法。您可以使用arm-elf-gccarm-elf-run
工具链提供的命令行模拟器来执行此操作。您可以从http://www.gnuarm.com/bu-2.16.1_gcc-4.0.2-c-c++_nl-1.14.0_gi-6.4_x86-64.tar.bz2下载工具链。(只需将存档解压缩到某个文件夹中,并可选择附加到系统的变量中)<path>/gunarm-4.0.2/bin/
PATH
首先,您需要将您的 ARM 代码安排到汇编 (.s) 文件中的汇编函数中,例如myasm.s
. 现在您需要用 C(test.c
例如)编写一个测试代码来调用汇编函数并使用我们熟悉的printf()
. 您可以在下面找到源代码:
myasm.s:
.align
.global myasmfunc @ Required, so that this func can be
@ accessed from main() in test.c
@ A sample asm function that
@ returns the value 6
myasmfunc: MOV R0, #5
ADD R0, R0, #1 @ Now R0 contains 6.
@ By the default ARM calling convention,
@ R0 will be used to pass return values
@ to the calling function
MOV PC, LR @ Return from myasmfunc()
测试.c:
#include <stdio.h>
int myasmfunc(void);
int main()
{
int retval = myasmfunc(); // The value that was in R0 now
// gets copied into retval
printf("retval = %d\n", retval); // And print it..
return 0;
}
准备好这两个文件后,您可以使用以下命令将它们构建为 ARM 二进制文件arm-elf-gcc
arm-elf-gcc -Wall test.c myasm.s -o test.out
然后使用运行二进制文件arm-elf-run
arm-elf-run ./test.out
retval = 6
这将在您的 Ubuntu 终端上打印一个:)
您可以使用此 git 存储库中的代码作为起点:
https://github.iu.edu/geobrown/c335-assembly-examples
正如其他人所提到的,您首先需要安装 QEMU 来模拟 ARM 硬件,并且您需要有一些编译代码的方法(我推荐CodeSourcery Lite Edition Toolchain)。然后编辑文件中的TOOLROOT
条目Makefile.common
以指向工具链的安装位置,并make test
在编写汇编代码并将其外部化到 C 测试文件后简单地运行命令。
此存储库中的代码提供了一堆示例,您可以根据自己的目的进行调整,C 测试文件将允许您调用汇编代码并将结果输出到 Ubuntu 中的终端。:)
我总是使用小型 qemu ARM VM 来测试 ARM 程序。
qemu-system-arm -localtime -m 256 -M versatilepb -kernel vmlinuz-2.6.32-5-versatile -initrd initrd.img-2.6.32-5-versatile -hda debian_squeeze_armel_standard.qcow2 -append "root=/dev/sda1" $@
由于它模拟了一个完整的 arm 系统,您可以在上面编写程序(例如使用 vim + gcc),然后在那里进行测试。
安装qemu,为arm交叉编译,然后使用
qemu-system-arm ./a.out
在您的终端上
不知道为什么还没有人提到它,但你可以使用Raspberry pi获得一个“真实”且价格合理的 arm 平台来进行试验。
默认情况下,Ubuntu 不附带它,据我所知,它附带一个名为 Raspbian 的 Debian remix (但也可以运行 Fedora、Arch 或 Debian plain)。
当谈到对该平台的支持时,有相应的书籍,它甚至还有自己的 Stack Exchange 子社区。
如果您打算用 C 编写一个 ARM 仿真器,您可以使用此存储库中的代码作为起点。 https://github.com/omufeed/ARMAssemblyEmulatorWithC 它有一个大小为 4 的管道。实现了数据处理指令,它处理溢出和进位标志。还实现了分支和中断。它接受汇编指令作为输入,并在指令完成后模拟最终的内存状态。添加了一些示例输入作为代码注释。在http://www.omidmufeed.com/arm-assembler-emulator-with-c/阅读更多内容