Resources:
ARM Assembly by Example
ARM instruction set
ARM Registers
EABI Syscall table
Stack frame
Sample programs
Divide in ARM-32
Get the files:
log on to Odin $ cd $ cd 2240/6 $ cp /home/fac/gordon/public_html/2240/code/lab6/* .
How to run an ARM-32 program on Odin ------------------------------------ 1. Write an ARM hello-world program named myhello.s vi myhello.s 2. Assemble your program, creating an object file. arm-linux-gnueabi-as myhello.s -o hello.o 3. Link and produce an executable file. arm-linux-gnueabi-ld hello.o -o hello 4. Run your executable ./hello
How to use the make utility to build your ARM programs ------------------------------------------------------ For myhello.s program... vi Makefile Enter the text below. all: hello hello: hello.o arm-linux-gnueabi-ld hello.o -o hello hello.o: hello.s arm-linux-gnueabi-as myhello.s -o hello.o clean: rm -f hello rm -f *.o Note: The indented line must use hard-tabs for indenting.
Copy hello.s to myhello.s
Modify myhello.s to display several times using a loop.
Use the assembler to create an object file.
Use the linker to create your executable file.
Run your program.
odin:~/2240/6$ arm-linux-gnueabi-as myhello.s -o hello.o odin:~/2240/6$ arm-linux-gnueabi-ld hello.o -o hello odin:~/2240/6$ ./hello Hello World! Hello World! Hello World! Hello World! Hello World! Hello World!
Play the 3-5-Bingo game.
Name your program: bingo.s
Write an ARM-32 program that displays the numbers 1 to 100.
but not all the numbers.
If a number is divisible by 3, display it.
If a number is divisible by 5, display it.
If a number is divisible by 3 and by 5, display Bingo!
Do you remember how to divide by 3 without a divide command?
Use Fixed-point math for this, using one of the ARM registers.
We will review this again in class.
====================================================================== How to divide by 3 and look at the remainder... 1. Multiply your number by 0x55555556 2. Look at the result in the low register only. 3. If the value is less than about 200, count it as zero. How to divide by 5 and look at the remainder... 1. Multiply your number by 0x33333334 2. Look at the result in the low register only. 3. If the value is less than about 200, count it as zero. Here is the result of the divides above on numbers 1 to 40. Notice there is some residue in the remainder, when it should be zero. Check for near zero in your tests. Not exactly zero. num rem remainder bit pattern --- --- -------------------------------- 3 2 00000000000000000000000000000010 5 4 00000000000000000000000000000100 6 4 00000000000000000000000000000100 9 6 00000000000000000000000000000110 10 8 00000000000000000000000000001000 12 8 00000000000000000000000000001000 15 10 00000000000000000000000000001010 15 12 00000000000000000000000000001100 18 12 00000000000000000000000000001100 20 16 00000000000000000000000000010000 21 14 00000000000000000000000000001110 24 16 00000000000000000000000000010000 25 20 00000000000000000000000000010100 27 18 00000000000000000000000000010010 30 20 00000000000000000000000000010100 30 24 00000000000000000000000000011000 33 22 00000000000000000000000000010110 35 28 00000000000000000000000000011100 36 24 00000000000000000000000000011000 39 26 00000000000000000000000000011010 40 32 00000000000000000000000000100000 Can you see where Bingo! should be printed? ====================================================================== Alternate method using ARM-32 sdiv command: As your numbers are listing, divide each with sdiv. sdiv quotient, dividend, divisor How to check for a remainder: multiply quotient times divisor if result is equal to dividend remainder is zero else remainder is not zero ====================================================================== There is a 3rd method also, which is to use counters: Do not use multiply or divide. Setup 3 counters using general purpose registers of your choice. Increment the counters each loop pass. Check your counters being equal to 3, 5, or 15. Reset the counters as needed. ====================================================================== Some extra credit for getting the program working multiple ways. 1. Fixed-point multiply method bingo.s 2. sdiv with multiply method bingo2.s 3. No divide or multiply bingo3.s ======================================================================
How to get started ------------------ 1. You can start with your myhello.s program loop. cp myhello.s bingo.s 2. Make your program display the numbers 1 through 20 or so. When you get that working... 3. Choose one of the methods described above.
Output sample...
$ ./bingo 3 5 6 9 10 12 Bingo! 18 20 21 ... ... ...
Fixed point format: 32-bit register: 0000000000000000.0000000000000000 integer fraction After a fixed-point divide: 32-bit register: 0000000000000000.0000000000000000 quotient remainder How would you look at just the fraction part of the register? Ask Gordon or Pablo for help.
The following programs will be collected
2240/6/myhello.s 2240/6/bingo.s 2240/6/Makefile 2240/6/bingo2.s 2240/6/bingo3.s I will assemble and run your bingo programs like this... arm-linux-gnueabi-as bingo.s -o bingo.o arm-linux-gnueabi-as atoi.s -o atoi.o arm-linux-gnueabi-as itoa.s -o itoa.o arm-linux-gnueabi-as printf.s -o printf.o arm-linux-gnueabi-ld bingo.o atoi.o itoa.o printf.o -o bingo ./bingo The first line will contain: bingo.s, bingo2.s, or bingo3.s