Reputation: 33
I would like to modify and complete an example found in my textbook (Harris-Harris). How can I make a program that declares an array of 5 elements for example and then increments each element by 10? This program must also print the elements of the array.
I've searched some resources and figured out that there are various ways to create an array in Assembly ARM. In these examples that I found, however, there are directives that I don't understand (for example .word or .skip) that are not explained in my textbook.
Upvotes: 0
Views: 730
Reputation: 773
Hope this helps. This example uses the stack to allocate the array.
See assembly memory allocation directives for more help on allocating global variables. Moving the variable scores
into global scope of the file test.c
below can reveal the assembly code for that sort of solution.
What is below comes from a quick walk thru of Hello world for bare metal ARM using QEMU
Output of these steps will add 10 to 5 array integers and print their values. The code is in c
but instructions are provided on how to display the code as assembly so you can study the array allocation and utilization.
Here is the expected output:
SCORE 10
SCORE 10
SCORE 10
SCORE 10
SCORE 10
ctrl-a x
QEMU: Terminated
These are the commands, notice startup.s
is assembly code, test.c
is c code like left side of your post, and test.ld
is a linker script file to create the image QEMU needs test.bin
to execute. Also, notice test.elf
is available with debug symbols for use in gdb
.
arm-none-eabi-as -mcpu=arm926ej-s -g startup.s -o startup.o
arm-none-eabi-gcc -c -mcpu=arm926ej-s -g test.c -o test.o
arm-none-eabi-ld -T test.ld test.o startup.o -o test.elf
arm-none-eabi-objcopy -O binary test.elf test.bin
qemu-system-arm -M versatilepb -m 128M -nographic -kernel test.bin
To examine assembly code in gdb see commands below.
Notice the array scores
in this code is on the stack, read about local stack variables for ARM assembly here and examine the assembly instructions below at 0x10888
where sp
is incremented by 24 (20 for scores
and 4 for i
).
qemu-system-arm -M versatilepb -m 128M -nographic -kernel test.bin -s -S
arm-none-eabi-gdb test.elf -ex "target remote:1234"
(gdb) b c_entry
(gdb) cont
(gdb) x/20i c_entry
0x10180 <c_entry>: push {r11, lr}
0x10184 <c_entry+4>: add r11, sp, #4
0x10188 <c_entry+8>: sub sp, sp, #24
I use a macbook and install tools like this, they end up in /usr/local/bin
:
brew install --cask gcc-arm-embedded
brew install qemu
The c code used is similar to what you posted and combines the article snip w/ a function to print an integer. References are inline of the code.
// test.c
// https://balau82.wordpress.com/2010/02/28/hello-world-for-bare-metal-arm-using-qemu/
volatile unsigned int *const UART0DR = (unsigned int *)0x101f1000;
void print_uart0(const char *s) {
while (*s != '\0') { /* Loop until end of string */
*UART0DR = (unsigned int)(*s); /* Transmit char */
s++; /* Next char */
}
}
// https://www.geeksforgeeks.org/c-program-to-print-all-digits-of-a-given-number/
void print_int(int N) {
#define MAX 10
char arr[MAX]; // To store the digit of the number N
int i = MAX - 1;
int minus = ( N < 0 );
int r;
arr[i--] = 0;
while (N != 0) { // Till N becomes 0
r = N % 10; // Extract the last digit of N
arr[i--] = r + '0'; // Put the digit in arr[]
N = N / 10; // Update N to N/10 to extract next last digit
}
arr[i] = ( minus ) ? '-' : ' ';
print_uart0(arr + i );
}
void c_entry() {
int i;
int scores[5] = {0, 0, 0, 0, 0};
for (i = 0; i < 5; i++) {
scores[i] += 10;
print_uart0("SCORE ");
print_int( scores[i] );
print_uart0("\n");
}
}
Using the same startup.s
assembly from article:
.global _Reset
_Reset:
LDR sp, =stack_top
BL c_entry
B .
Using the same linker script from article:
ENTRY(_Reset)
SECTIONS
{
. = 0x10000;
.startup . : { startup.o(.text) }
.text : { *(.text) }
.data : { *(.data) }
.bss : { *(.bss COMMON) }
. = ALIGN(8);
. = . + 0x1000; /* 4kB of stack memory */
stack_top = .;
}
Upvotes: 1