Node structure used in the linked list examples
 

struct Node definition used in using ARM assembler programming examples:

   struct Node
   {
      int          value1;   // Data field 1  offset = 0
      short        value2;   // Data field 2  offset = 4
      short        value3;   // Data field 3  offset = 6
      struct Node  *next;    // Link field    offset = 8
   }  

 

Background information:

  • In order to show you how to access data field in a linked list, I will need to create a linked list...

  • List objects (= nodes) are created with the malloc( ) function

  • For simplicity, I will create a linked list using assembler directives inside the .data section

Creating a linked list using assembler directives

How I created a linked list using assembler directives:

Example of a linked list with 5 nodes:

p0: .4byte  333         // Object [333,23,33,p2]
    .2byte  23, 33
    .4byte  p2
    .skip 4             // gap
p1: .4byte  111         // Object [111,21,31,p3]
    .2byte  21, 31
    .4byte  p3
p2: .4byte  444         // Object [444,24,34,p4]
    .2byte  24, 34
    .4byte  p4
    .skip 4             // gap
p3: .4byte  222         // Object [222,22,32,p0]
    .2byte  22, 32
    .4byte  p0
    .skip 4             // gap
p4: .4byte  555         // Object [555,25,35,null]
    .2byte  25, 35
    .4byte  0           // 0 = null 

head: .4byte  p1    

The first list element (= node) is p1 !! (Can you see it ?)

Creating a linked list using assembler directives

The assembler directives created the following linked list:

head ⇒ [111,21,31,•]⇒[222,22,32,•] ⇒[333,23,33,•]⇒[444,24,34,•]⇒[555,25,35,null]

p0: .4byte  333         // Object [333,23,33,p2]
    .2byte  23, 33
    .4byte  p2
    .skip 4             // gap
p1: .4byte  111         // Object [111,21,31,p3]
    .2byte  21, 31
    .4byte  p3
p2: .4byte  444         // Object [444,24,34,p4]
    .2byte  24, 34
    .4byte  p4
    .skip 4             // gap
p3: .4byte  222         // Object [222,22,32,p0]
    .2byte  22, 32
    .4byte  p0
    .skip 4             // gap
p4: .4byte  555         // Object [555,25,35,null]
    .2byte  25, 35
    .4byte  0           // 0 = null  

head: .4byte  p1        // head contains address p1

DEMO: /home/cs255001/demo/asm/4-linked-list/demo2.s

Review:   how to calculate the offset of fields in a (list) object - Example 2

Given the following struct Node (object) definition:

   struct Node
   {
      int   value1;   // Data field 1
      short value2;   // Data field 2
      short value3;   // Data field 3
      List  next;     // Link field  
   };  

The offset of the fields in objects defined by the above class definition are:

   Offset(value1) = 0
   Offset(value2) = 4
   Offset(value3) = 6 (4+2)
   Offset(next)   = 8 (4+2+2)

 

We now discuss how to access a list element using ARM assembler code

Linked list access example 1:   load data fields in the first object in the list into registers R1, R2, R3  

Write ARM assembler code to:

  • load (= fetch)   head.value1,value2,value3   into registers R1, R2, R3, respectively

 ARM assembler instructions:       

   // Fetch: head.value1, 2 and 3

  
 

  

   

  
 
   


  

DEMO:   /home/cs255001/demo/asm/4-linked-list/demo2.s

Linked list access example 1:   load data fields in the first object in the list into registers R1, R2, R3  

The variables value1, value2 and value3 are fetched using load instructions with their corresponding offsets:

 ARM assembler instructions:       

   // Fetch: head.value1, 2 and 3

   // Preparation:
   //   r0 = base address


   ldr   r1, [r0, #0]//Offset(v1)=0
   ldrsh r2, [r0, #4]//Offset(v2)=4
   ldrsh r3, [r0, #6]//Offset(v3)=6
  
  



  

Required preparation :   r0 = base address of the first Node "object" (struct)

Linked list access example 1:   load data fields in the first object in the list into registers R1, R2, R3  

The variable head contains the base address of the first Node "object" (struct):

 ARM assembler instructions:       

   // Fetch: head.value1, 2 and 3

   // Preparation:
   //   r0 = head


   ldr   r1, [r0, #0]//Offset(v1)=0
   ldrsh r2, [r0, #4]//Offset(v2)=4
   ldrsh r3, [r0, #6]//Offset(v3)=6
  
  



  

DEMO:   /home/cs255001/demo/asm/4-linked-list/demo2.s

Linked list access example 1:   load data fields in the first object in the list into registers R1, R2, R3  

Solution:   assembler code to load (= fetch)   head.value1,value2,value3   into registers R1, R2, R3:

 ARM assembler instructions:       

   // Fetch: head.value1, 2 and 3

   movw  r0, #:lower16:head
   movt  r0, #:upper16:head
   ldr   r0, [r0]    // R0 = head

   ldr   r1, [r0, #0]//Offset(v1)=0
   ldrsh r2, [r0, #4]//Offset(v2)=4
   ldrsh r3, [r0, #6]//Offset(v3)=6





  

DEMO:   /home/cs255001/demo/asm/4-linked-list/demo2.s

Linked list access example 2:   load data fields in the 2nd object in the list into registers R1, R2, R3  

Write assembler code to:

  • load (= fetch)   head.next.value1,value2,value3   into registers R1, R2, R3, respectively

 ARM assembler instructions:       

 // Fetch: head.next.val1, 2 and 3

  
 

  

   

  
 
   


  

DEMO:   /home/cs255001/demo/asm/4-linked-list/demo2.s

Linked list access example 2:   load data fields in the 2nd object in the list into registers R1, R2, R3  

The variables value1, value2 and value3 are fetched using load instructions with their corresponding offsets:

 ARM assembler instructions:       

 // Fetch: head.next.val1, 2 and 3

 // Preparation:
 //   r0 = base address






 ldr   r1, [r0, #0]//Offset(v1)=0
 ldrsh r2, [r0, #4]//Offset(v2)=4
 ldrsh r3, [r0, #6]//Offset(v3)=6
  
  

Required preparation :   r0 = base address of the 2nd Node "object" (struct)

Linked list access example 2:   load data fields in the 2nd object in the list into registers R1, R2, R3  

The base address of the 2nd list object is stored in the variable head.next:

 ARM assembler instructions:       

 // Fetch: head.next.val1, 2 and 3

 // Preparation:
 //   r0 = head.next






 ldr   r1, [r0, #0]//Offset(v1)=0
 ldrsh r2, [r0, #4]//Offset(v2)=4
 ldrsh r3, [r0, #6]//Offset(v3)=6
  
  

DEMO:   /home/cs255001/demo/asm/4-linked-list/demo2.s

Linked list access example 2:   load data fields in the 2nd object in the list into registers R1, R2, R3  

We must start by fetching head in register R0:

 ARM assembler instructions:       

 // Fetch: head.next.val1, 2 and 3

 // Preparation:
 //   r0 = head.next

 movw  r0, #:lower16:head
 movt  r0, #:upper16:head
 ldr   r0, [r0]    // r0=head


 ldr   r1, [r0, #0]//Offset(v1)=0
 ldrsh r2, [r0, #4]//Offset(v2)=4
 ldrsh r3, [r0, #6]//Offset(v3)=6
  
  

Then:   use R0 to fetch head.next (next has offset=8) into R0 !!!

Linked list access example 2:   load data fields in the 2nd object in the list into registers R1, R2, R3  

Complete solution:   assembler code to load (= fetch)   head.value1,value2,value3   into registers R1, R2, R3:

 ARM assembler instructions:       

 // Fetch: head.next.val1, 2 and 3

 // Preparation:
 //   r0 = head.next

 movw  r0, #:lower16:head
 movt  r0, #:upper16:head
 ldr   r0, [r0]    // r0=head
 ldr   r0, [r0,#8] // r0=head.next

 ldr   r1, [r0, #0]//Offset(v1)=0
 ldrsh r2, [r0, #4]//Offset(v2)=4
 ldrsh r3, [r0, #6]//Offset(v3)=6

  

DEMO:   /home/cs255001/demo/asm/4-linked-list/demo2.s

Linked list example without pictures....

Fetch the following variable into register R1:

   r1 = head.next.next.value2  

Solution:

 


  
 
  

  
 

  

DEMO:   /home/cs255001/demo/asm/4-linked-list/demo2.s

Linked list example without pictures....

Fetch the following variable into register R1:

   r1 = head.next.next.value2  

Solution:

  movw   r0, #:lower16:head
  movt   r0, #:upper16:head
  ldr    r0, [r0]              // r0 = head
 
  

  

 

  

DEMO:   /home/cs255001/demo/asm/4-linked-list/demo2.s

Linked list example without pictures....

Fetch the following variable into register R1:

   r1 = head.next.next.value2  

Solution:

  movw   r0, #:lower16:head
  movt   r0, #:upper16:head
  ldr    r0, [r0]              // r0 = head
  ldr    r0, [r0, #8]          // r0 = head.next

  

 


  

DEMO:   /home/cs255001/demo/asm/4-linked-list/demo2.s

Linked list example without pictures....

Fetch the following variable into register R1:

   r1 = head.next.next.value2  

Solution:

  movw   r0, #:lower16:head
  movt   r0, #:upper16:head
  ldr    r0, [r0]              // r0 = head
  ldr    r0, [r0, #8]          // r0 = head.next
  ldr    r0, [r0, #8]          // r0 = head.next.next
  
  // We now have: r0 = base address of the required list object
 


  

DEMO:   /home/cs255001/demo/asm/4-linked-list/demo2.s

Linked list example without pictures....

Fetch the following variable into register R1:

   r1 = head.next.next.value2  

Solution:

  movw   r0, #:lower16:head
  movt   r0, #:upper16:head
  ldr    r0, [r0]              // r0 = head
  ldr    r0, [r0, #8]          // r0 = head.next
  ldr    r0, [r0, #8]          // r0 = head.next.next

  ldrsh  r1, [r0, #4]          // r1 = head.next.next.value2

 

  

DEMO:   /home/cs255001/demo/asm/4-linked-list/demo2.s

Assignment example with linked list

Translate the following assignment statement into ARM assembler:

   head.next.next.value2 = 99;  

Solution:

 


  
 
  

  
 

  

DEMO:   /home/cs255001/demo/asm/4-linked-list/demo2.s

Assignment example with linked list

Translate the following assignment statement into ARM assembler:

   head.next.next.value2 = 99;  

Solution:

   // Get the RHS first
   mov    r0, #99                // r0 = 99

 
 
  
 
 
  

   

DEMO:   /home/cs255001/demo/asm/4-linked-list/demo2.s

Assignment example with linked list

Translate the following assignment statement into ARM assembler:

   head.next.next.value2 = 99;  

Solution:

   // Get the RHS first
   mov    r0, #99                // r0 = 99

   // Preparation: base address r1 = head.next.next
 
   
  
 
 


DEMO:   /home/cs255001/demo/asm/4-linked-list/demo2.s

Assignment example with linked list

Translate the following assignment statement into ARM assembler:

   head.next.next.value2 = 99;  

Solution:

   // Get the RHS first
   mov    r0, #99                // r0 = 99

   // Preparation: base address r1 = head.next.next
   movw   r1, #:lower16:head
   movt   r1, #:upper16:head      // r1 = addr(head)
   ldr    r1, [r1]                // r1 = head
    


 

DEMO:   /home/cs255001/demo/asm/4-linked-list/demo2.s

Assignment example with linked list

Translate the following assignment statement into ARM assembler:

   head.next.next.value2 = 99; 

Solution:

   // Get the RHS first
   mov    r0, #99                // r0 = 99

   // Preparation: base address r1 = head.next.next
   movw   r1, #:lower16:head
   movt   r1, #:upper16:head      // r1 = addr(head)
   ldr    r1, [r1]                // r1 = head
   ldr    r1, [r1, #8]            // r1 = head.next



DEMO:   /home/cs255001/demo/asm/4-linked-list/demo2.s

Assignment example with linked list

Translate the following assignment statement into ARM assembler:

   head.next.next.value2 = 99;  

Solution:

   // Get the RHS first
   mov    r0, #99                // r0 = 99

   // Preparation: base address r1 = head.next.next 
   movw   r1, #:lower16:head
   movt   r1, #:upper16:head      // r1 = addr(head)
   ldr    r1, [r1]                // r1 = head
   ldr    r1, [r1, #8]            // r1 = head.next
   ldr    r1, [r1, #8]            // r1 = head.next.next

  // We now have: r1 = base address of the required list object

DEMO:   /home/cs255001/demo/asm/4-linked-list/demo2.s

Assignment example with linked list

Translate the following assignment statement into ARM assembler:

   head.next.next.value2 = 99; 

Solution:

   // Get the RHS first
   mov    r0, #99                // r0 = 99

   // Preparation: base address r1 = head.next.next - DONE !
   movw   r1, #:lower16:head
   movt   r1, #:upper16:head      // r1 = addr(head)
   ldr    r1, [r1]                // r1 = head
   ldr    r1, [r1, #8]            // r1 = head.next
   ldr    r1, [r1, #8]            // r1 = head.next.next

   strh   r0, [r1, #4]            // Offset(value2) = 4

DEMO:   /home/cs255001/demo/asm/4-linked-list/demo2.s

Assignment example with linked list

Translate the following assignment statement into ARM assembler:

   head.value1 = head.next.next.value3;  

Solution:

   // Get head.next.next.value3
  
  
   
 
  
  

 
  
  
  

                                  

DEMO:   /home/cs255001/demo/asm/4-linked-list/demo2.s

Assignment example with linked list

Translate the following assignment statement into ARM assembler:

   head.value1 = head.next.next.value3;  

Solution:

   // Get head.next.next.value3
   movw   r0, #:lower16:head
   movt   r0, #:upper16:head      // r0 = addr(head)
   ldr    r0, [r0]                // r0 = head
  
  
  

 
  
  
  

                                  

DEMO:   /home/cs255001/demo/asm/4-linked-list/demo2.s

Assignment example with linked list

Translate the following assignment statement into ARM assembler:

   head.value1 = head.next.next.value3;  

Solution:

   // Get head.next.next.value3
   movw   r0, #:lower16:head
   movt   r0, #:upper16:head      // r0 = addr(head)
   ldr    r0, [r0]                // r0 = head
   ldr    r0, [r0, #8]            // r0 = head.next
  
  

 
  
  
  

                                  

DEMO:   /home/cs255001/demo/asm/4-linked-list/demo2.s

Assignment example with linked list

Translate the following assignment statement into ARM assembler:

   head.value1 = head.next.next.value3;  

Solution:

   // Get head.next.next.value3
   movw   r0, #:lower16:head
   movt   r0, #:upper16:head      // r0 = addr(head)
   ldr    r0, [r0]                // r0 = head
   ldr    r0, [r0, #8]            // r0 = head.next
   ldr    r0, [r0, #8]            // r0 = head.next.next
  

 
  
  
  

                                  

DEMO:   /home/cs255001/demo/asm/4-linked-list/demo2.s

Assignment example with linked list

Translate the following assignment statement into ARM assembler:

   head.value1 = head.next.next.value3;  

Solution:

   // Get head.next.next.value3
   movw   r0, #:lower16:head
   movt   r0, #:upper16:head      // r0 = addr(head)
   ldr    r0, [r0]                // r0 = head
   ldr    r0, [r0, #8]            // r0 = head.next
   ldr    r0, [r0, #8]            // r0 = head.next.next
   ldrsh  r0, [r0, #6]            // r0 = head.next.next.value3

   // Store r0 in head.value1
  
  
  

                                  

DEMO:   /home/cs255001/demo/asm/4-linked-list/demo2.s

Assignment example with linked list

Translate the following assignment statement into ARM assembler:

   head.value1 = head.next.next.value3;  

Solution:

   // Get head.next.next.value3
   movw   r0, #:lower16:head
   movt   r0, #:upper16:head      // r0 = addr(head)
   ldr    r0, [r0]                // r0 = head
   ldr    r0, [r0, #8]            // r0 = head.next
   ldr    r0, [r0, #8]            // r0 = head.next.next
   ldrsh  r0, [r0, #6]            // r0 = head.next.next.value3

   // Store r0 in head.value1
   movw   r1, #:lower16:head
   movt   r1, #:upper16:head      // r0 = addr(head)
   ldr    r1, [r1]                // r0 = head
  
   

DEMO:   /home/cs255001/demo/asm/4-linked-list/demo2.s

Assignment example with linked list

Translate the following assignment statement into ARM assembler:

   head.value1 = head.next.next.value3;  

Solution:

   // Get head.next.next.value3
   movw   r0, #:lower16:head
   movt   r0, #:upper16:head      // r0 = addr(head)
   ldr    r0, [r0]                // r0 = head
   ldr    r0, [r0, #8]            // r0 = head.next
   ldr    r0, [r0, #8]            // r0 = head.next.next
   ldrsh  r0, [r0, #6]            // r0 = head.next.next.value3

   // Store r0 in head.value1
   movw   r1, #:lower16:head
   movt   r1, #:upper16:head      // r0 = addr(head)
   ldr    r1, [r1]                // r0 = head
 
   str    r0, [r1, #0]            // offset(value1) = 0  (int)   

DEMO:   /home/cs255001/demo/asm/4-linked-list/demo2.s