Well-written project documentation clarifies intent, documents decisions and results, and allows project managers to assess project progress (and report it, as necessary, to project stakeholders) at e
Prof. Pitts CS556AH1: Computer Architecture Fall 2018 ARM Programming Project For this project, you'll use the subset of ARM instruction provide by the VisUAL emulator (download the zip at this address and extract to use the emulator) to implement the algorithms given below in ARM assembly language. You'll submit your ARM assembly language programs through Canvas as a ZIP file.
The programs that you will translate into ARM instructions are shown below. A user guide for the VisUAL emulator is found here . The remainder of the document is some useful information regarding the ARM assembly language.
int [] vals = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; int [] results = new int[10]; int count = 0; int bnd = 10; while (count < bnd) { if ( vals[count] % 1 == 0 ) results[count] = vals[count] * 2; else results[count] = vals[count] + 1; } int num1 = 36; int num2 = 54; while ( num1 != num2 ) { while ( num1 > num2) { num1 = num1 - num2; } while ( num2 > num1 ) { num2 = num2 - num1; } } The ARM instruction set supported by the VisUAL emulator The complete set of ARM instructions supported by the VisUAL emulator is shown in the Appendix 1 of this document. The purpose of this document is to provide some guidance as to how to use the instruction set in your project responses.
There are a few general categories of ARM instructions that you'll need to use:
• data transfer instructions: These instructions move data from one location to another.
◦ MOV and MVN: move data between registers and also allow you to move immediate values into a register. Note immediate values must be preceded with a # character (MOV R0, #10, which moves the value 10 into register zero).
◦ LDR and STR: the load and store instructions, which move data between memory and the registers. The standard way the the instructions are used is to have the target address in a register. To load an address into a register, the LDR pseudo-instruction is used:
LDR R2, =count LDR R7, [R2] This code places the memory address represented by the label count into register two (first instruciion), then loads the value in the memory location at count into register seven (second instruction).
• arithmetic and logic instructions: these instructions perform the standard arithmetic and logic operations on data in registers (and immediate data). These are three operand instructions and the first two must be registers, while the third may be an immediate.
• testing instructions: these instruction (particularly CMP, TST, and TEQ) are described in Appendix 2. They are arithmetic/logic instructions which do not store their result (and so have only two operands). They are used two test conditions.
• branch instructions: the VisUAL emulator supports only the B and BL (branch and link instruction that can be used for procedure calls). Both are by default unconditional, but can be made conditional as described in Appendix 2.
• data directives: The EQU, DCD, FILL, and END instructions are not machine instructions but tell the emulator how to interpret names (the first three) and when to stop (the last). EQU creates named constants that can be used any where an immediate on address can be used. DCE allow the initialization of a sequence of memory locations (by default, 32 bit integers). FILL allows the reservation of n bytes of uninitialized memory locations.
There are a couple of common translations from the high-level language constructs (if, if-else, while) you are used to and assembly language instructions. Some examples are shown below:
count = 0; while (count < 10) { count = count + 1; } count DCD 0 ldr R2, =count ldr R3, [R2] top CMP R3, #10 BLT loop B finish loop add R3, R3, #1 STR R3, [R2] B top finish end 1 / 6 Prof. Pitts CS556AH1: Computer Architecture Fall 2018 var1 = 4; var2 = 0; var3 = 0; if (var1 <= 10) var2 = var2 + 1; else var3 = var3 + 1; var1 DCD 4 var2 DCD 0 var3 DCD 0 ldr R2, =var1 ldr R3, [R2] CMP R3, #10 BGT greater ldr r2, =var2 ldr R3, [R2] add R3, R3, #1 STR R3, [R2] B fin greater ldr R2, =var3 ldr R3, [R2] add R3,R3, #1 STR R3, [R2] fin end Another important aspect of ARM assembly to understand for this project, are the addressing mode. As seen above, the programs use a simple, register indirect addressing mode. To deal with data in an array, one of the indexing modes needs to be used. The most straightforward is the post-indexed form, as show in this example:
ldr R2, =var ldr R3, [R2], #4 In this code, the address of a label var (assumed to be the beginning of a block of integers) is placed in register two by the first instruction. The second instruction load the value in that address indirectly through register 2 into register 3 and the increments register 2 by four, moving the the address in R2 to point to the next integer.
2 / 6 Prof. Pitts CS556AH1: Computer Architecture Fall 2018 Appendix 1 This is a copy of the page https://salmanarif.bitbucket.io/visual/supported_instructions.html from the official VisUAL emulator website https://salmanarif.bitbucket.io/visual/index.html for your convenience. The complete User Guide for the VisUAL emulator can be found at https://salmanarif.bitbucket.io/visual/user_guide/index.html .
List of Supported Instructions VisUAL supports a small subset of ARM UAL instructions. These are primarily arithmetic, logical, load/store and branch instructions. A short summary of the instruction syntax is given below. For detailed information and examples, press Ctrl+Space when typing an instruction opcode in the code editor.
Summary Opcode Syntax Move MOV MOV{S}{cond} dest, op1 {, SHIFT_op #expression} Move Negated MVN MVN{S}{cond} dest, op1 {, SHIFT_op #expression} Address Load ADR ADR{S}{cond} dest, expression LDR Psuedo-Instruction LDR LDR{S}{cond} dest, =expression Add ADD ADD{S}{cond} dest, op1, op2 {, SHIFT_op #expression} Add with Carry ADC ADC{S}{cond} dest, op1, op2 {, SHIFT_op #expression} Subtract SUB SUB{S}{cond} dest, op1, op2 {, SHIFT_op #expression} Subtract with Carry SBC SBC{S}{cond} dest, op1, op2 {, SHIFT_op #expression} Reverse Subtract RSB RSB{S}{cond} dest, op1, op2 {, SHIFT_op #expression} Reverse Subtract with Carry RSC RSC{S}{cond} dest, op1, op2 {, SHIFT_op #expression} Bitwise And AND AND{S}{cond} dest, op1, op2 {, SHIFT_op #expression} Bitwise Exclusive Or EOR EOR{S}{cond} dest, op1, op2 {, SHIFT_op #expression} Bitwise Clear BIC BIC{S}{cond} dest, op1, op2 {, SHIFT_op #expression} Bitwise Or ORR ORR{S}{cond} dest, op1, op2 {, SHIFT_op #expression} Logical Shift Left LSL LSL{S}{cond} dest, op1, op2 Logical Shift Right LSR LSR{S}{cond} dest, op1, op2 Arithmetic Shift Right ASR ASR{S}{cond} dest, op1, op2 Rotate Right ROR ROR{S}{cond} dest, op1, op2 Rotate Right and Extend RRX RRX{S}{cond} op1, op2 Compare CMP CMP{cond} op1, op2 {, SHIFT_op #expression} Compare Negated CMN CMN{cond} op1, op2 {, SHIFT_op #expression} Test Bit(s) Set TST TST{cond} op1, op2 {, SHIFT_op #expression} Test Equals TEQ TEQ{cond} op1, op2 {, SHIFT_op #expression} Load Register LDR LDR{B}{cond} dest, [source {, OFFSET}] Offset addressing LDR{B}{cond} dest, [source, OFFSET]! Pre-indexed addressing LDR{B}{cond} dest, [source], OFFSET Post-indexed addressing Store Register STR STR{B}{cond} source, [dest {, OFFSET}] Offset addressing STR{B}{cond} source, [dest, OFFSET]! Pre-indexed addressing STR{B}{cond} source, [dest], OFFSET Post-indexed addressing Load Multiple Registers LDM[dir] LDM[dir]{cond} source, {list of registers} Store Multiple Registers STM[dir] STM[dir]{cond} dest, {list of registers} Branch B B{cond} target Branch with Link BL BL{cond} target Declare Word(s) in Memory DCD name DCD value_1, value_2, ... value_N Declare Constant EQU name equ expression Declare Empty Word(s) in Memory FILL {name} FILL N N must be a multiple of 4 Stop Emulation END END{cond} For a comprehensive guide on these instructions and to see examples, browse the ARM Infocenter website here .
3 / 6 Prof. Pitts CS556AH1: Computer Architecture Fall 2018 Notes • For all instructions that require dest , op1 , & op2 , dest and op1 must be registers.
• expression is a numerical constant or expression that evaluates to a 32-bit number. The operators + , - and * are allowed. A constant is a decimal number as a series of digits 0-9 , a hexadecimal number prefixed with 0x or & or a binary number prefixed with 0b . An additional restriction is that this number must be creatble by rotating an 8-bit number right by an even number of bits within a 32-bit word.
• For MOV / MVN, dest must be a register.
• For CMP / CMN / TST / TEQ, op1 must be a register.
• {...} indicates optional code.
• {cond} refers to the condition code . An official list of instruction codes can be seen here .
• {S} is the set bit . If this is present, the status bits will be set. The exact mechanism of these differs for each instruction. See the instruction summary page on ARM Infocenter website for details here .
• {, SHIFT_op #expression} means a shift operation can be performed on op2 as part of the same instruction. The shifted version of op2 is then used as the second operand for the main instruction. This feature is part of the flexible second operand feature of ARM UAL.
• SHIFT_op can be any one of LSL, LSR, ASR, ROR, RRX.
• With the exception of RRX, #expression can be a register from R0 through R15 or any numerical expression.
• op2 cannot be R15 or PC if a shift is being used.
• For MOV / MVN / ADR, op1 is used instead.
• {, OFFSET} refers to the offset applied to the source address or destination address for load and store instructions respectively. It can be a register, a numerical expression, or a shifted register (like the flexible second operand discussed earlier).
• Load and Store Instructions indexing modes:
• If ] is present after the first operand, post-indexing is used. This means that the destination pointer is updated with the value (current value + offest) after the load/store operation is completed. You can observe this by example using the "Show Pointer" visualisation feature.
• If ! is present at the end, pre-indexing is used. This means the destination pointer is updated with the value (current value + offset) before the load/store operation is performed. You can observe this by example using the "Show Pointer" visualisation feature.
• There are a total of 9 possible indexing modes. A good summary is provided here .
• {B} refers to byte mode . By default, the LDR / STR instructions load a word (32 bits) from the memory at the given address. If B is used, the byte at the given address is loaded instead. Note that the convention for byte addressing is Little Endian . You can observe memory access operations and compare word/byte modes using the "Show Memory" visualisation feature.
• For LDM and STM instructions, [dir] indicates stack direction. This can be one of full ascending FA , full descending FD , empty ascending EA , and empty descending ED . You can also use aliases for these as described in the link that follows. The operation of these instructions is provided in detail on this ARM Infocenter page .
• The target for a branch instruction B must be a label on a line. This instruction will cause the program to "jump", i.e. branch, to this line of code.
• Branch with link BL is identical to branch, with the additional function that the link register is set to point to the next line of code before the branch is performed. This can be used to return from a subroutine.
• For EQU , expression can be any numerical expression.
4 / 6 Prof. Pitts CS556AH1: Computer Architecture Fall 2018 Disclaimer The information provided on this page is given on an as is basis, for the purpose of supporting the VisUAL application and its users to debug code. It may be not be up to date with official ARM UAL guidelines at the time you are using it. Always up-to-date information can be found here .
5 / 6 Prof. Pitts CS556AH1: Computer Architecture Fall 2018 Appendix 2 This list of condition codes that can be use with ARM instructions (along with the flag conditions they set) are taken from the website https://community.arm.com/processors/b/blog/posts/condition-codes-1-condition-flags-and-codes . The two letter codes in the first column may be add to any of the ARM instructions in Appendix 1. But more particularly, if you want to perofrm a conditional branch in your program, you would append the appropriate two letter code to the ARM B instruciton (the basic unconditional branch instruciton).
The ARM flags (N-negative result, Z - zero result, C - unsigned overflow, V - signed overflow) are set by the arithmetic and logic instructions of the ARM processor (ADD, SUB, AND, OR, etc), plus the special testing instructions (CMP , TST, and TEQ for example). The CMP performs a subtraciton of its two operands without assignment the result, while TST performs a bitwise AND of its two operands, and TEQ performs a bitwise XOR of its two operands.
CMP is typically used to compare two values: if the result is negative the first operand is less than the second; if the result is positive, the first operand is greater than the second; and if the result is zero, the two operands are equal. A CMP instruction, followed by a BEQ, BNE, BLT, BGT, performs a condition branch depending on the operancs were equal, not equal, first less than the second, or the first greater than the second, respectively.
TST is used to test whether specific bis are set in a word: one operand holds the value to be tested, while the other operand has ones in the bits to be tested.
If the result is non-zero, one of the bits tested was set, while if the result is zero, none ot the tested bits were set.
TEQ is an alternate way to test for equality, without affecting the unsigned or signed overflow flags. Unlike CMP, this instruction only allows testing of equality, not ordering. It also provides a convenient way of testing the sign bit of a value as after TEQ, the sign flag is the exclusive or of the sign bits in the operands.
Code Meaning (for cmp or subs) Flags Tested eq Equal. Z==1 ne Not equal. Z==0 cs or hs Unsigned higher or same (or carry set). C==1 cc or lo Unsigned lower (or carry clear). C==0 mi Negative. The mnemonic stands for "minus". N==1 pl Positive or zero. The mnemonic stands for "plus". N==0 vs Signed overflow. The mnemonic stands for "V set". V==1 vc No signed overflow. The mnemonic stands for "V clear". V==0 hi Unsigned higher. (C==1) && (Z==0) ls Unsigned lower or same. (C==0) || (Z==1) ge Signed greater than or equal. N==V lt Signed less than. N!=V gt Signed greater than. (Z==0) && (N==V) le Signed less than or equal. (Z==1) || (N!=V) al (or omitted) Always executed. None tested.
6 / 6