good_evening
good_evening

Reputation: 21729

Simulating ARM code

I would like to simulate ARM code. For example, I want to run code like this:

MOV    R0, #5
ADD    R0, R0, #1
//somehow output R0

And it would output 6 on some software on my Ubuntu. Is it possible?

Upvotes: 9

Views: 10620

Answers (10)

nav
nav

Reputation: 1655

I guess what you're after is a way to printf the value returned by an ARM assembly function, from a C program. You can do this using the command-line simulator arm-elf-run available with arm-elf-gcc toolchain. You can download the toolchain from 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. (Just unpack the archive into some folder, and optionally append <path>/gunarm-4.0.2/bin/ to your system's PATH variable)

To start with, you need to arrange your ARM code into an assembly function inside an assembly (.s) file, say myasm.s. Now you need to write a test code in C (test.c, for instance) to call the assembly function and printf the returned value using our familiar printf(). You can find the source code below:

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()

test.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;
}

Once the two files are ready, you can build them into an ARM binary using arm-elf-gcc

arm-elf-gcc -Wall test.c myasm.s -o test.out

And then run the binary using arm-elf-run

arm-elf-run ./test.out

This will print a retval = 6 on your Ubuntu terminal :)

Upvotes: 2

omufeed
omufeed

Reputation: 162

If you are planning to write an ARM emulator in C, you can use the code in this repository as a starting point. https://github.com/omufeed/ARMAssemblyEmulatorWithC It has a pipeline of size 4. Data processing instructions are implemented and it handles the overflow and carry flags. Branch and interrupts are also implemented. It accepts an assembly instruction as input and simulates the final memory state after the instruction completion. There are some example inputs added as code comments. Read more at http://www.omidmufeed.com/arm-assembler-emulator-with-c/

Upvotes: 0

BeniBela
BeniBela

Reputation: 16907

I always use a small qemu ARM VM to test ARM programs.

You can download it from debian and then run it with: (more infos)

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" $@

Since it simulates a full arm system, you can write the programs on it (e.g. with vim + gcc) and then test them there.

Upvotes: 1

NlightNFotis
NlightNFotis

Reputation: 9805

Not sure why noone has mentioned it yet, but you can get a "real" and affordable arm platform to experiment with, with Raspberry pi.

It doesn't come with Ubuntu by default, to my knowledge it come's with a Debian remix called Raspbian (but can also run Fedora, Arch or Debian plain).

When it comes for support of that platform, there are books for that and it even has its own Stack Exchange sub community.

Upvotes: 0

Praveen Felix
Praveen Felix

Reputation: 1428

Keil MDK can be used to simulate the ARM codes. It provides a Simulate/Debug perspective which can be used to probe the ARM register set, memory content, etc...

MDK-Lite evaluation version is available free of cost for a maximum code size of 32KB.

Linux version of MDK is not available. But Keil MDK works perfectly over WINE in Ubuntu.


Keil uVision MDK Installation on WINE:

Step 1: Install wine on Ubuntu

Open a terminal and type:

sudo apt-get install wine

Step 2: Download Keil MDK.

Step 3: Install MDK

Right-Click on MDK executable file and select "Open With Wine Windows Program Loader" option.

Step 4: Invoke Keil uVision MDK on Ubuntu

Open a terminal and type:

wine ~/.wine/drive_c/Keil/UV4/Uv4.exe

Step 5: Install Flash Magic (Optional)

Flash Magic is a tool used to download software for Keil boards. Download Flash Magic Software and install it on wine (refer previous steps).

Create a COM1 link to serial port. Open a terminal and type:

ln -s /dev/ttyS0 ~/.wine/dosdevices/COM1

Keil uVision MDK Project Creation and Debugging:

Step 1: Create a Keil UVision project for ARM7 target.

In Keil UVision tool bar select Project --> New Project.

Navigate to a location where you want to create this project.

Enter a project name and click Save.

Select ARM --> ARM7(Little Endian) as device for Target. Click OK.

Step 2: Create an assembly source file for the target

In Keil UVision tool bar select File --> New. Add the following code to the newly created file:

    AREA text, code, readonly
    ENTRY

    MOV    R0, #5
    ADD    R0, R0, #1

    END

Provide tab-space before each assembly statement as done above. Save the file with '.s' extension.

Step 3: Add source file to project

In Project window (located left side of UVision), Right click on Source Group 1 and select "Add Files to Group Source Group 1" option.

Select test.s and click 'Add'. (Select File Type as ASM Source file)

enter image description here

Step 4: Build source file

In Keil UVision tool bar select Project --> Build target or Press F7 to compile the source file.

Step 5: Simulate/Debug application

In Keil UVision tool bar select Debug--> Start/Stop Debug Session or Press Ctrl + F5.

The debug perspective opens up with a Register view at left side, Code View at center, Memory view at right bottom, etc...

enter image description here

Use the debugging keys to execute the code:

enter image description here

Observe Register view at end of program execution:

enter image description here

In Keil UVision tool bar select Debug--> Start/Stop Debug Session or Press Ctrl + F5 to come out of Debugging Perspective.

Upvotes: 12

Santosh
Santosh

Reputation: 799

Install qemu, cross compile it for arm, and then use

qemu-system-arm ./a.out

on your terminal

Upvotes: 0

junix
junix

Reputation: 3211

This article gives a step by step introduction into using QEMU for simulating baremetal ARM code: http://balau82.wordpress.com/2010/02/28/hello-world-for-bare-metal-arm-using-qemu/

Of course you don't need to take care of the C stuff and can place your assembly directly in the startup.s

Upvotes: 3

tcdowney
tcdowney

Reputation: 337

You can use the code in this git repository as a starting point:

https://github.iu.edu/geobrown/c335-assembly-examples

As others have mentioned you'll first need to install QEMU to emulate the ARM hardware and you will need to have some way of compiling your code (I recommend the CodeSourcery Lite Edition Toolchain). Then edit the TOOLROOT entry in the Makefile.common file to point to the installation location of your toolchain and simply run the command make test after you have written your assembly code and externed it into your C test file.

The code in this repository provides a bunch of examples that you can adapt to your own purposes and the C test files will allow you to call your assembly code and output the results to your terminal in Ubuntu. :)

Upvotes: 1

Filippo Savi
Filippo Savi

Reputation: 397

you could run arm code through QEMU that is an emulator but I don't think you can output directly to another pice of software because QEMU is also a software but you could use something like shared memory or even a file (warning concurrent access to a file may require a mutex) to pass results from the emulator to the host software and back even if it could be a little slow

Upvotes: 3

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 798436

If you build it into an actual executable then you can use QEMU's ARM emulator to run it.

Upvotes: 10

Related Questions