0% found this document useful (0 votes)
7 views76 pages

Lecture 4 (B) - ARM Architecture - Part 2

The document covers topics in computer organization and architecture, specifically focusing on decoding hexadecimal to assembly language, condition codes, and procedures in LEGv8 assembly. It provides examples of converting hexadecimal instructions to assembly code, explains branching instructions, and discusses condition codes used for decision-making in assembly programming. Additionally, it highlights the significance of carry and overflow flags in arithmetic operations and their implications for signed and unsigned comparisons.

Uploaded by

deepakbond008
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views76 pages

Lecture 4 (B) - ARM Architecture - Part 2

The document covers topics in computer organization and architecture, specifically focusing on decoding hexadecimal to assembly language, condition codes, and procedures in LEGv8 assembly. It provides examples of converting hexadecimal instructions to assembly code, explains branching instructions, and discusses condition codes used for decision-making in assembly programming. Additionally, it highlights the significance of carry and overflow flags in arithmetic operations and their implications for signed and unsigned comparisons.

Uploaded by

deepakbond008
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 76

23CSE213

Computer Organization and


Architecture
Decoding (Hex to Assembly), Condition codes, Procedures

Department of CSE
2024-25 Even semester
Contents
• Decoding (Hex to Assembly)
• Condition codes
• Procedures

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 2


Decoding
• Encoding is the process of converting the assemble language to hexadecimal
format.

• Decoding is the reverse process.


• Given a hexadecimal code, convert to assembly language.
• Since there are variety of formats, to understand this concept, restrict to D and
R format.

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 3


Example 1
• Convert to assembly code
• 8B150289 10001011000101010000001010001001
• Check the format by seeing the first 11 bits - 458 16.
• ADD is the function for 45816.
• Use the R-format for dividing the 32-bit instruction into instruction fields.
11 5 6 5 5
10001011000 10101 000000 10100 01001
ADD X21 0 X20 X9

• ADD X9, X20, X21

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 4


Example 2
• Convert to assembly code
• CA0C0149 11001010000011000000000101001001
• Check the format by seeing the first 11 bits - 650 16.
• EOR is the function.
• Use the R-format for dividing the 32-bit instruction into instruction fields.
11 5 6 5 5
110010100 01100 000000 01010 01001
00
EOR X12 0 X10 X9
• EOR X9, X10, X12

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 5


Example 3
• Convert to assembly code
• D340792A 1101001101000000 0111100100101010
• Check the format by seeing the first 11 bits – 69A 16.
• LSR is the function.
• Use the R-format for dividing the 32-bit instruction into instruction fields.
11 5 6 5 5
110100110 00000 011110 01001 01010
10
LSR 0 30 X9 X10
• LSR X10, X9, #30

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 6


Example 4
• Convert to assembly code
• F80182C9 11111000000000011000001011001001
• Check the format by seeing the first 11 bits – 7C0 16.
• STUR is the function.
• Use the D-format for dividing the 32-bit instruction into instruction fields.
11 9 2 5 5
11111000000 000011000 00 10110 01001
STUR 24 0 X22 X9

• STUR X9, [X22, #24]

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 7


Revisiting branching instructions
• LEGv8 Code:
• 𝐵 𝐿1 // Branch to statement with label L1

• B L1
• ADD X10,X11,X12 //Skipped
• L1 : SUBX10,X11,X12

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 8


Instructions for making decisions
• Define Labels for instructions.
• LEGv8 Code:
L1 : ADDX9,X21,X9

• Instruct computer to branch to instruction using the label if some condition is


satisfied.
• CBZ compare and branch if zero
• CBNZ compare and branch if not zero
• LEGv8 Code:
• 𝐶𝐵𝑍 𝑟𝑒𝑔𝑖𝑠𝑡𝑒𝑟,𝐿1 // if (register == 0) branch to instruction labeled
• 𝐶𝐵𝑁𝑍 𝑟𝑒𝑔𝑖𝑠𝑡𝑒𝑟,𝐿1 // if (register != 0) branch to instruction labeled

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 9


Example 1
• CBZ X9, L2
• L1 : ADDX10,X11,X12 Checks to see if the value in
register is 0. If yes, branches to
• L2 : SUBX10,X11,X12 L2

X9 X9
1 0

CBZ X9, L2 CBZ X9, L2


L1 : ADDX10,X11,X12 L1 : ADDX10,X11,X12
L2 : SUBX10,X11,X12 L2 : SUBX10,X11,X12

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 10


Example 2
• Write a conditional assembly code for

If (x == 0)
f = f + 20
else if (x == 1)
f=f–1
else
f=f+1

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 11


Solution
• CBZ X9, L2
• SUBI X11, X9, 1 \ checking for x==1
• CBZ X11, L1
• ADDI X10, X10, #1
• B EXIT

• L1
• SUBI X10, X10, #1
• B EXIT

• L2:
• ADDI X10, X10, #20
• Exit:

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 12


Loop statements
• The C code for an infinite while loop that continuously increments a variable
k can be written as:

while (True){
k = k + 1;
}
Compiled LEGv8 code:
• Loop: ADDI X24, X24, #1
• B Loop

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 13


Example 3
• Write the LEGv8 assembly code for the following c code: Assume k is in
X24.

while (True){ Loop:


ADDI X24, X24, #1
k = k + 1;
SUBI X25, X24, #10
if (k == 10){ CBZ X25, Exit
Break; B Loop
} Exit:
}

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 14


Example 4
• Write the LEGv8 assembly code for the following c code: Assume i in x22, k
in x24, address of save in x25
• while (save[i] == k)
i += 1;
Loop:
LSL X10,X22,#3 // X10 = i*23
ADD X10,X10,X25 // Address to load save[i]
LDUR X9,[X10,#0] // load save[i]
SUB X11,X9,X24 // X11 = save[i] –k
CBNZ X11,Exit // conditional branch
ADDI X22,X22,#1 // i += 1
B Loop // uncond. Branch
Exit: …

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 15


Negative (N)
Condition codes Zero (Z)
Overflow (V)
• LEGv8 provides four added bits
Carry (C)
called condition codes. Condition
Codes are used to store the result of
comparison operations and help in the condition flags are stored in a special-purpose
conditional branching. register called the Program Status Register
(PSR). Specifically, the condition flags are located
• Some arithmetic instructions can in the NZCV field of the Current Program Status
optionally set these flags based on Register (CPSR).

the result of the operation.


• Then the branch (B) instruction can negative (N): result had 1 in MSB
check these bits to do comparisons. zero (Z): result was 0
overflow (V): result overflowed
carry (C): result had carryout from MSB
23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 16
Signed vs unsigned
• Signed comparison (Both positive and negative)
Signed numbers
• Unsigned comparison (Only Positive) Bit pattern with a 1 – negative
• Example number is less than any positive
• X22 = 1111 1111 1111 1111 1111 1111 1111 1111 number.
• X23 = 0000 0000 0000 0000 0000 0000 0000 0001
Unsigned numbers
• X22 < X23 # signed
1 in the most significant bit
• –1 < +1
represents a number that is larger
• X22 > X23 # unsigned
than any that begins with a 0.
• +4,294,967,295 > +1

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 17


Carry
• The carry flag (C) is used to indicate whether an arithmetic operation (usually
addition) has produced a result that exceeds the maximum value that can be
represented with the available number of bits. (In Unsigned)
• Addition:
• If the result of adding two numbers exceeds the maximum value representable
in the given bit-width (e.g., for an 8-bit register, if the sum exceeds 255).
• Subtraction:
• In the context of subtraction, if borrow not needed, then the carry flag may
also be set.
• Example:
• Adding 0xFF (255) and 0x01 (1) in an 8-bit context:
• Result: 0x100 (256), which cannot be represented in 8 bits.
• Carry flag is set to indicate the overflow.

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 18


Carry
•Carry (C):
Set to 1 if there is a carry-out in addition or no borrow in subtraction.
Set to 0 if there is no carry-out in addition or a borrow occurs in
subtraction.

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 19


The range of signed 32-bit integers is:
Overflow −231 (0x80000000, or −2147483648) to +231−1
(0x7FFFFFFF, or +2147483647).
• The overflow flag (V) indicates whether the result of an arithmetic operation exceeds the
range that can be represented by the signed integer format.
•Addition:
•Overflow occurs when the signs of the operands are the same, and the sign of the result is
different. Eg: adding two +ve numbers results in a -ve number.
•Subtraction:
•Overflow occurs when the signs of the operands are different, and the sign of the result is the
same as the subtrahend.
•Addition:
•Adding 0x7FFFFFFF (maximum positive 32-bit signed integer) and 0x1:
•Result: 0x80000000 (minimum negative 32-bit signed integer).
•Overflow flag is set because the operation resulted in a sign change from positive to negative.
•Subtraction:
•Subtracting 13 from -7: Subtracting -13 from -7: no overflow
•Result: 0x7FFFFFFF, which is valid.
• Overflow occurs.
23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 20
Overflow

•Overflow (V):
•Set to 1 when the signed result of an addition or subtraction exceeds the range
of the signed number representation.
•For example, adding two positive numbers results in a negative, or adding two
negatives results in a positive.

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 21


Comparison
Feature Carry Flag (C) Overflow Flag (V)
Exceeding the maximum value in Exceeding the range in signed
Indicates
unsigned arithmetic arithmetic
Relevant primarily for addition
Relevant for both addition and
Context and subtraction of signed
subtraction
integers
Adding two large positive
Adding two large unsigned
Example signed numbers resulting in a
numbers
negative

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 22


Negative (N)
Condition codes Zero (Z)
Overflow (V)
• LEGv8 provides four added bits
Carry (C)
called condition codes. Condition
Codes are used to store the result of
comparison operations and help in the condition flags are stored in a special-purpose
conditional branching. register called the Program Status Register
(PSR). Specifically, the condition flags are located
• Some arithmetic instructions can in the NZCV field of the Current Program Status
optionally set these flags based on Register (CPSR).

the result of the operation.


• Then the branch (B) instruction can negative (N): result had 1 in MSB
check these bits to do comparisons. zero (Z): result was 0
overflow (V): result overflowed
carry (C): result had carryout from MSB
23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 23
Conditional branch - combinations
• Conditional branches - use combinations of these condition codes to perform
the desired sets.
• Signed: (6 conditions)
• EQ ( = or Equal) it will check the status of zero flag (Z) in the processor's status
register (CPSR in ARM). // Z=1
• NE (≠ or Not Equal) // Z=0 Unsigned: (4 conditions)
• LT (< or Less Than) • LO (< or Lower)
• LE (≤ or Less than or Equal) • LS (≤ or Lower or Same)
• GT (> or Greater Than) • HI (> or Higher)
• GE (≥ or Greater than or Equal). • HS (≥ or Higher or Same)

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 24


Branching with condition codes
• LEGv8 includes these four branches to
complete the testing of the individual condition
code bits: Negative (N)
• Branch on minus (B.MI): N= 1;(Means negative Zero (Z)
number) Overflow (V)
• Branch on plus (B.PL): N= 0; (Means Positive Carry (C)
number)
• Branch on overflow set (B.VS): V= 1;
• Branch on overflow clear (B.VC): V= 0.

MOV R0, #5 // Load 5 into R0


SUB R1, R0, #10 // Subtract 10 from R0 and store in R1 // R1 = 5 - 10 = -5, N flag is set (negative result)
B.MI NEGATIVE // Branch to NEGATIVE if the result is negative (N=1)

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 25


Set flags
• Since Condition codes create several options, these codes are limited to only
certain instructions.
• ADD, ADDI, AND, ANDI, SUB, SUBI.
• condition code – enabled based on choice (append S).
• Set from arithmetic instruction with S-suffix.
• ADDS, ADDIS, ANDS, ANDIS, SUBS, SUBIS
• Eg:- ADDS is understood as ADD and set flag.

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 26


23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 27
23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 28
Instruction and Condition Code (CC) test

* Result might appear negative due to overflow


and hence we need to check for overflow also.
Negative (N) Overflow (V)
Zero (Z) Carry (C)

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 29


Example 1
• LEGv8 provides set flag variants for SUB
• 𝐴𝑠𝑠𝑢𝑚𝑒 𝑖=+9, j = +10 are signed integers, and store in X1, and X2
respectively.
• To do the comparison
• If (i < j), result is -1. Negative (N) 1
Zero (Z) 0
Overflow (V) 0
Carry (C) 0
• 𝑆𝑈𝐵𝑆 𝑋1,𝑋1,𝑋2

A borrow occurred during subtraction. So C=0

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 30


Example 2
Negative (N) 0
• If X1=10, and X2=10 Zero (Z) 1
𝑆𝑈𝐵𝑆 𝑋1,𝑋1,𝑋2 Overflow (V) 0
Carry (C) 1

ADDS X1, X2, X3 (X2 = 7, and X3 = 5)


Negative (N) 0
Zero (Z) 0
Overflow (V) 0
Carry (C) 0

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 31


Example 3
• if (a > b)
a += 1;

a in X22, b in X23

SUBS X9,X22,X23 // use subtract to make comparison


B.LT Exit // conditional branch
ADDI X22,X22, #1

Exit:

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 32


Example 4
• while (True)
k=k+1 Loop:
ADDI X24, X24, #1 The result of the subtract
if (k > 10)
SUBIS X25, X24, #10 instruction is redundant,
break B.GT uses the condition
B.GT Exit flags for branching For
B Loop efficiency, we can give the
destination register as
Exit: XZR instead of X25

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 33


Example 5
• Alternate method:
Loop:
ADDI X24, X24, #1
SUBIS XZR, X24, #10
B.GT Exit
B Loop

Exit:

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 34


Example 6
• Consider the following LEGv8 loop:
• LOOP:
SUBIS X1, X1, #0
B.LE DONE
SUBI X1, X1, #1
ADDI X0, X0, #2
B LOOP
• DONE:
• Assume that the register X1 is initialized to the value 10. What is the final value in
register X0 assuming the X0 is initially zero?
• Write equivalent C-code?
• For the loop written in LEGv8 assembly above, replace the instruction “B.LE
DONE” instruction with “B.MI DONE”. What is the final value in register X0
assuming the X0 is initially zero?
23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 35
Solution

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 36


Example 7
• Translate the following loop into C. Assume that the C-level integer i is held in register
X10, X0 holds the C-level integer called result, and X1 holds the base address of the
integer MemArray.

ORR X10, XZR, XZR


LOOP: LDUR X11, [X1, #0]
ADD X0, X0, X11
ADDI X1, X1, #8
ADDI X10, X10, #1
CMPI X10, 100
B.LT LOOP

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 37


Solution
• int result = 0; // X0 corresponds to result, initialized to 0
• int i = 0; // X10 corresponds to the loop index, initialized to 0
• int *MemArray = ...; // X1 corresponds to the base address of MemArray

• while (i < 100) { // Loop condition: i < 100 (CMPI X10, 100 and B.LT LOOP)
• result += MemArray[i]; // Add MemArray[i] to result (LDUR X11 and ADD X0, X0,
X11)
• i++; // Increment i (ADDI X10, X10, #1)
•}

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 38


Alternate solution
int i = 0; // Initialize i (X10) to 0
int result = 0; // Initialize result (X0) to 0

do {
int value = *(int *)X1; // Load the value from memory at address X1
result += value; // Add the value to result
X1 += 8; // Increment the memory address by 8 bytes (size of int in a 64-bit system)
i++; // Increment the loop counter i
} while (i < 100); // Check if i (X10) is less than 100

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 39


Procedures
• A procedure or function is one tool programmers use to structure
programs, both to make them easier to understand and to allow code
to be reused.
• With procedures, you can break a large task into smaller parts and
concentrate on solving one part at a time.
• Parameters act as an interface between the procedure and the rest of
the program and data, since they can pass values and return results.
• Parameters are the values passed to a procedure when it is called.
• Implement abstraction in software.
• When you use a built-in function like sort(array), you don’t need to
know the sorting algorithm used internally.

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 40


Example: Procedures
Function: calculate(a,b)
Parameter: a, b
Argument: 5, 7

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 41


Execution of a procedure
1. Put parameters in a place where the procedure can access them.
2. Transfer control to the procedure.
3. Acquire the storage resources needed for the procedure. (Storing the result)
4. Perform the desired task.
5. Put the result value in a place where the calling program can access it.
6. Return control to the point of origin, since a procedure can be called from
several points in a program. (Return address)

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 42


Registers and Instruction for procedures
• X0–X7: eight parameter registers in which to pass parameters (argument
values) or return values. X0 for return value.
• LR (X30): one return address register to return to the point of origin. “Link
Register”.
• A specific instruction for procedure branches to an address and simultaneously
saves the address of the following instruction in register LR (X30).
• The branch-and-link instruction (BL) is simply written
• BL ProcedureAddress

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 43


Link?
• This “link register,” stored in register LR (register 30), is called the return
address.
• An address or link is formed that points to the calling site to allow the
procedure to return to the proper address. (This ensures the program knows
where to resume execution after the procedure is complete.)
• Same procedure could be called from several parts of the program – so return
address is compulsory.
• LEGv8 use the branch register instruction (BR) - unconditional branch to the
address specified in a register:
• BR LR: When a procedure completes, executing BR LR sends the program
counter (PC) back to the calling instruction’s address stored in LR.

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 44


Example of the code

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 45


Program control – Order of Executions
Main function Procedure
Caller Callee
1. Puts parameters into X0-X7 as required
by callee function
2. Use BL instruction. Control to be
transferred to Callee and Next instruction to
be stored in LR.
3. Performs the calculations
4. Places the result in X0-X7
5. Use BR to return to the address as
mentioned in LR
6. Continue with next instruction execution.

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 46


Stored-program idea
• Need a register to hold the address of the current instruction being executed.
• Generally termed as Program Counter.
• More meaningful term is instruction address register.

• The BL instruction actually saves PC + 4 in register LR to link to the byte


address of the following instruction to set up the procedure return. (e.g., 4
bytes for a 32-bit instruction).

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 47


Concern:
• If the program needs more registers : X0-X7 is not sufficient?

• User can take up registers.


• Any registers needed by the caller must be restored to the values that they
contained before the procedure was invoked.
• This ensures that the caller doesn't lose its data after the procedure completes.
• Use the Stack registers
• used to store the data of additional registers as needed by the procedure.
• Once procedure completes the use of the register, the data from stack will be replaced
in the register – Leave no trace of using the register.

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 48


Example

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 49


Stack
• The ideal data structure for spilling registers is a stack—a last-in-first-out
queue.
• A stack needs a pointer to the most recently allocated address in the stack to
show where the next procedure should place the registers to be spilled or
where old register values are found.
• The stack pointer (SP) – X28 - is adjusted by one doubleword means 8 bytes
for each register that is saved or restored.
• Operations:
• Push - placing data onto the stack
• Pop - removing data from the stack
• Stack Pointer (SP): Keeps track of the top of the stack.

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 50


Accessing Stack
• Stacks “grow” from higher addresses to lower addresses.
• This convention means that you push values onto the stack by subtracting
from the stack pointer.
• Memory stack v/s Register stack

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 51


STP (Store Pair)
• STP <reg1>, <reg2>, [<base_register>, #offset]!
• <reg1> and <reg2>: Registers to store.
• <base_register>: Memory address register (e.g., SP for stack pointer).
• #offset: Adjusts the address (optional). The ! updates the base register after
the operation.
• STP X0, X1, [SP, #-16]!
LDP (Load Pair)
• LDP <reg1>, <reg2>, [<base_register>], #offset
LDP X0, X1, [SP], #16

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 52


Procedures in ARMv8

• Procedure can be explained in two ways:


• Leaf procedure:
• Procedure which do not call another function.
• Key Characteristics of Leaf Procedures:
• It performs its tasks without invoking other procedures.
• Requires minimal management of the stack (e.g., no need to save the return
address multiple times).
• Easier to implement since it doesn’t involve nested calls.
23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 53
Procedures in ARMv8
• Nested procedure:
• Procedure which calls another function.
• Key Characteristics of Nested
Procedures:
• Requires saving and restoring the return
address (and sometimes registers) on the
stack to avoid overwriting them.
• May require managing multiple levels of
procedure calls.
• Typically uses the stack for proper function
return and to save intermediate data.

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 54


Leaf procedure
• C code:
long long int leaf_example (long long int g, long
long int h, long long int i, long long int j)
{ long long int f;
f = (g + h) - (i + j);
return f;
}
• Arguments g, …, j in X0, …, X3
• f in X19 (hence, need to save $s0 on stack)

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 55


Leaf procedure
• The parameter variables g, h, i, and j correspond to the argument registers X0,
X1, X2, and X3, and f corresponds to X19.
• X9 and X10 are the temporary registers required in the calculations.

Step 1: Save registers X19, temporary registers (X9 and X10) into stack
// adjust stack to make room for 3 items
SUBI SP, SP, #24
STUR X10, [SP,#16]
STUR X9, [SP,#8]
STUR X19, [SP,#0]

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 56


Step 2: Perform the calculations
• ADD X9,X0,X1 // register X9 contains g + h
• ADD X10,X2,X3 // register X10 contains i + j
• SUB X19,X9,X10 // f = X9 − X10, which is (g + h) −
(i + j)
Step 3: To return the value of f, copy it into a parameter register
• ADD X0,X19,XZR // returns f (X0 = X19 + 0)

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 57


Step 4: Before returning, restore the three old values of the registers from the
stack:
• LDUR X19, [SP,#0] // restore register X19 for caller
• LDUR X9, [SP,#8] // restore register X9 for caller
• LDUR X10, [SP,#16] // restore register X10 for
caller
• ADDI SP,SP,#24 // adjust stack to delete 3 items
Step 5: The procedure ends with a branch register using the return address:
• BR LR // branch back to calling routine

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 58


Full code for Leaf procedure
• Assembly code
leaf_example:
C code:
// Step 1: Set up the stack frame long long int leaf_example (long long int g, long
SUBI SP, SP, #24 long int h, long long int i, long long int j)
STUR X10, [SP,#16] { long long int f;
STUR X9, [SP,#8] f = (g + h) - (i + j);
STUR X19, [SP,#0] return f;
// Step 2: Perform computation }
ADD X9,X0,X1 // register X9 contains g + h
ADD X10,X2,X3 // register X10 contains i + j
SUB X19,X9,X10 // f = X9 − X10, which is (g + h) − (i + j)
• // Step 3: Restore stack frame Thinks to remember to preserved the values
LDUR X19, [SP,#0] // restore register X19 for caller Registers X19–X28: These are callee-saved registers.

LDUR X9, [SP,#8] // restore register X9 for caller Procedure argument/ result X0-X7

LDUR X10, [SP,#16] // restore register X10 for caller Link Register (X30): Must be preserved if your function calls other
ADDI SP,SP,#24 // adjust stack to delete 3 items functions.
// Step 4: Restore stack frame If you need extra storage for intermediate
Temporary Registers (Optional):

BR LR // branch back to calling routine values (e.g., when you're running out of registers), you can save
temporary registers (X9–X15) to the stack and restore them later.

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 59


Better code without saving temporary
What can be made better? register values:
• To avoid saving and restoring a SUBI SP,SP,#8
register whose value is never used, STUR X19,[SP,#0]
which might happen with a
temporary register, LEGv8 software ADD X9,X0,X1
separates 19 of the registers into two ADD X10,X2,X3
groups: SUB X19,X9,X10
• X9–X17: temporary registers that are
not preserved by the callee (called ADD X0,X19,XZR
procedure) on a procedure call
• X19–X28: saved registers that must LDUR X19,[SP,#0]
be preserved on a procedure call (if ADDI SP,SP,#8
used, the callee saves and restores
them) BR LR

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 60


Example
long long int modified_example(long long int x, long long int y, long long int z, long long int w) {
long long int result;

// Perform simple arithmetic operations


result = (x + y) - (z * w); // Add and subtract with multiplication

return result; Lets store argument (X-X0, Y-X1, Z-X2, X-


} X3),
X9 & X10 temporary register. Result to
int main() { X19
long long int x = 5, y = 10, z = 2, w = 3;
long long int result = modified_example(x, y, z, w);
printf("The result is: %lld\n", result);
return 0;
}

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 61


Solution
MOV x0, #5
MOV x1, #10
MOV x2, #2
MOV x3, #3
modified_example:
SUBI SP, SP,#8
STUR X19, [SP,#0]

ADD X9,X0,X1
MUL X10,X2,X3
SUB X19,X9,X10

ADD X0,X19,XZR

LDUR X19,[SP,#0]
ADDI SP,SP,#8

BR LR

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 62


Example 2
long long int modified_example(long long int x, long long int y, long long int z, long long int w) {
long long int result;
// Perform complex arithmetic operations
long long int temp1 = x + y; // First addition
long long int temp2 = z * w; // Multiplication
long long int temp3 = temp1 * temp2; // Multiply addition result with multiplication result
long long int temp4 = temp3 / 10; // Division by 10
long long int temp5 = temp4 /7; // Division by 7

// Final result with subtraction and bitwise shift


result = (temp5 - (temp3 >> 2)) & 0xFF; // Bitwise AND with 0xFF
return result;
}
int main() {
long long int x = 5, y = 10, z = 2, w = 3;
long long int result = modified_example(x, y, z, w);
printf("The result is: %lld\n", result);
return 0;
}
23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 63
Solution
MOV x0, #5 // x = 5 Note: If the function is standalone and you don't need to preserve X19,
MOV x1, #10 // y = 10 you can eliminate the stack-related instructions (SUBI, STUR, LDUR, and
MOV x2, #2 // z = 2 ADDI) entirely. Here’s how the optimized code would look:
MOV x3, #3 // w = 3

modified_example:
ADD X9, X0, X1
MUL X10, X2, X3
MUL X11, X9, X10
UDIV X12,X11,#10
UDIV X13,X12,#7
SUBI SP, SP, #8
STUR X19, [SP,#0]
LSR X14, X11, #2
SUB X14, X13, X14
AND X19, X14, 0XFF
ADD X0,X19,XZR
LDUR X19,[SP,#0]
ADDI SP,SP,#8
BR LR

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 64


Nested Procedures
Refer to the situation where one procedure (or function) calls another
procedure within it.
Ex.

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 65


Nested Procedures
• Suppose that the main program calls procedure A with an argument of 3, by
placing the value 3 into register X0 and then using BL A.
• Then suppose that procedure A calls procedure B via BL B with an argument
of 7, also placed in X0 by overwriting.
• Since A hasn’t finished its task yet, there is a conflict over the use of register
X0.
• There is a conflict over the return address in register LR, since it now has the
return address for B.

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 66


Solution?
• Caller needs to save on the stack:
• Its return address (LR)
• Any arguments and temporaries needed after the call (E.g. X0, X1)
• Restore from the stack after the call

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 67


Nested Procedure
• C code:

int fact (int n)


{
if (n < 1) return 1;
else return n * fact(n - 1);
}

• Argument n in X0 (Argument)
• Result in X1

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 68


Nested Procedure:
Step 1: Starts with the label of the procedure and then saves two registers on
the stack, the return address X1 and X0.
• fact:
• SUBI SP, SP, #16 // adjust stack for 2 items
• STUR LR, [SP,#8] // save the return address
• STUR X0, [SP,#0] // save the argument n
Step 2: First Compare n if 0 or more.
• SUBIS XZR, X0, #1 //test if n<1
• B.GE L1 // if n >=1, goto L1

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 69


• Step 3:
• If n is less than 1, fact returns 1 by putting 1 into a value register: it adds 1 to 0
and places that sum in X1. It then pops the two saved values off the stack and
branches to the return address.
• ADDI X1,XZR, #1 // return 1
• ADDI SP,SP,#16 // Pop stack, don’t bother restoring values
• BR LR // return to caller
• If n is not less than 1, the argument n is decremented and then fact is called
again with the decremented value:
• L1: SUBI X0,X0,#1 // n >= 1: argument gets (n − 1)
• BL fact // call fact with (n − 1)

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 70


Step 4: Now the old return address and old argument are restored, along with the
stack pointer:
• LDUR X0, [SP,#0] // return from BL: restore argument n
• LDUR LR, [SP,#8] // restore the return address
• ADDI SP, SP, #16 // adjust stack pointer to pop 2
items

Step 5: Next, the value register X1 gets the product of old argument X0 and the
current value of the value register.
• MUL X1,X0,X1 // return n * fact (n − 1)

Step 6: Finally, fact branches again to the return address:


• BR LR // return to the caller
23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 71
Complete program – Nested procedure
fact: BL fact
SUBI SP,SP,#16 LDUR X0,[SP,#0]
STUR LR,[SP,#8] LDUR LR,[SP,#8]
STUR X0,[SP,#0] ADDI SP,SP,#16
SUBIS XZR,X0,#1 MUL X1,X0,X1
B.GE L1 BR LR
ADDI X1,XZR,#1
ADDI SP,SP,#16
BR LR
L1: SUBI X0,X0,#1
23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 72
Example 2
• int fact (int n)
{
if (n >0){
return n * fact(n - 1);
}
else {
return 1;
}
}

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 73


Allocating Space for New Data on the Stack
• Stack is also used to store variables that are local to the procedure but do not
fit in registers, such as local arrays or structures.
• The segment of the stack containing a procedure’s saved registers and local
variables is called a procedure frame or activation record.
• A frame pointer (FP) to point to the first doubleword of the frame of a
procedure.
• A stack pointer might change during the procedure, and so references to a
local variable in memory might have different offsets depending on where
they are in the procedure, making the procedure harder to understand.
• Alternatively, a frame pointer offers a stable base register within a procedure
for local memory-references. Note that an activation record appears on the
stack whether or not an explicit frame pointer is used.
23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 74
Stack allocation
• (FP or X29) points to the first
doubleword of the frame.
• Stack pointer (SP) points to the
top of the stack.

• The stack is adjusted to make room for all the saved registers and any
memory-resident local variables.
• Stable frame pointer
• If there are no local variables on the stack within a procedure, the compiler
will save time by not setting and restoring the frame pointer.
• When a frame pointer is used, it is initialized using the address in SP on a
call, and SP is restored using FP.
23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 75
Working of SP and FP:
• When a function is called:
• The current SP is pushed onto the
stack.
• The value of the current FP is also
pushed onto the stack.
• The SP is updated to point to the new
stack frame.
• The FP is set to the current SP value,
marking the beginning of the current
function's stack frame

23-01-2025 Dept of CSE, Amrita School of Computing, Coimbatore 76

You might also like