Lab 05 - Assembly Language Lab

 Assembly Language Lab

In this lab, I will demonstrate the steps I took to convert the output from decimal to hexadecimal. This will include modifying the message, extending the code and changing the code as needed. 

STEP 0:

Unpacking the archive provided to us by using this command: cd ~ ; tar xvf /public/spo600-assembler-lab-examples.tgz

commands used: 
cd ~ : Change directory to home
tar: To archive file 

STEP 1: 

There are a few steps before printing the object code and disassembling it into assembler for every binaries. Down below I will describe each command used to complete step 1.

x86_64 Server: 

cd ~/spo600/examples/hello/c: Change directory to test c files
make: Compiles dependencies and defines what codes to run
Objdump -d hello: This will print out the object code

Below is the 

hello:     file format elf64-x86-64



Disassembly of section .init:


0000000000401000 <_init>:

  401000: f3 0f 1e fa          endbr64

  401004: 48 83 ec 08          sub    $0x8,%rsp

  401008: 48 8b 05 d1 2f 00 00 mov    0x2fd1(%rip),%rax        # 403fe0 <__gmon_start__@Base>

  40100f: 48 85 c0             test   %rax,%rax

  401012: 74 02                je     401016 <_init+0x16>

  401014: ff d0                call   *%rax

  401016: 48 83 c4 08          add    $0x8,%rsp

  40101a: c3                   ret


Disassembly of section .plt:


0000000000401020 <printf@plt-0x10>:

  401020: ff 35 ca 2f 00 00    push   0x2fca(%rip)        # 403ff0 <_GLOBAL_OFFSET_TABLE_+0x8>

  401026: ff 25 cc 2f 00 00    jmp    *0x2fcc(%rip)        # 403ff8 <_GLOBAL_OFFSET_TABLE_+0x10>

  40102c: 0f 1f 40 00          nopl   0x0(%rax)


0000000000401030 <printf@plt>:

  401030: ff 25 ca 2f 00 00    jmp    *0x2fca(%rip)        # 404000 <printf@GLIBC_2.2.5>

  401036: 68 00 00 00 00       push   $0x0

  40103b: e9 e0 ff ff ff       jmp    401020 <_init+0x20>


Disassembly of section .text:


0000000000401040 <_start>:

  401040: f3 0f 1e fa          endbr64

  401044: 31 ed                xor    %ebp,%ebp

  401046: 49 89 d1             mov    %rdx,%r9

  401049: 5e                   pop    %rsi

  40104a: 48 89 e2             mov    %rsp,%rdx

  40104d: 48 83 e4 f0          and    $0xfffffffffffffff0,%rsp

  401051: 50                   push   %rax

  401052: 54                   push   %rsp

  401053: 45 31 c0             xor    %r8d,%r8d

  401056: 31 c9                xor    %ecx,%ecx

  401058: 48 c7 c7 26 11 40 00 mov    $0x401126,%rdi

  40105f: ff 15 73 2f 00 00    call   *0x2f73(%rip)        # 403fd8 <__libc_start_main@GLIBC_2.34>

  401065: f4                   hlt

  401066: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1)

  40106d: 00 00 00 


0000000000401070 <_dl_relocate_static_pie>:

  401070: f3 0f 1e fa          endbr64

  401074: c3                   ret

  401075: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1)

  40107c: 00 00 00 

  40107f: 90                   nop


0000000000401080 <deregister_tm_clones>:

  401080: b8 10 40 40 00       mov    $0x404010,%eax

  401085: 48 3d 10 40 40 00    cmp    $0x404010,%rax

  40108b: 74 13                je     4010a0 <deregister_tm_clones+0x20>

  40108d: b8 00 00 00 00       mov    $0x0,%eax

  401092: 48 85 c0             test   %rax,%rax

  401095: 74 09                je     4010a0 <deregister_tm_clones+0x20>

  401097: bf 10 40 40 00       mov    $0x404010,%edi

  40109c: ff e0                jmp    *%rax

  40109e: 66 90                xchg   %ax,%ax

  4010a0: c3                   ret

  4010a1: 66 66 2e 0f 1f 84 00 data16 cs nopw 0x0(%rax,%rax,1)

  4010a8: 00 00 00 00 

  4010ac: 0f 1f 40 00          nopl   0x0(%rax)


00000000004010b0 <register_tm_clones>:

  4010b0: be 10 40 40 00       mov    $0x404010,%esi

  4010b5: 48 81 ee 10 40 40 00 sub    $0x404010,%rsi

  4010bc: 48 89 f0             mov    %rsi,%rax

  4010bf: 48 c1 ee 3f          shr    $0x3f,%rsi

  4010c3: 48 c1 f8 03          sar    $0x3,%rax

  4010c7: 48 01 c6             add    %rax,%rsi

  4010ca: 48 d1 fe             sar    $1,%rsi

  4010cd: 74 11                je     4010e0 <register_tm_clones+0x30>

  4010cf: b8 00 00 00 00       mov    $0x0,%eax

  4010d4: 48 85 c0             test   %rax,%rax

  4010d7: 74 07                je     4010e0 <register_tm_clones+0x30>

  4010d9: bf 10 40 40 00       mov    $0x404010,%edi

  4010de: ff e0                jmp    *%rax

  4010e0: c3                   ret

  4010e1: 66 66 2e 0f 1f 84 00 data16 cs nopw 0x0(%rax,%rax,1)

  4010e8: 00 00 00 00 

  4010ec: 0f 1f 40 00          nopl   0x0(%rax)


00000000004010f0 <__do_global_dtors_aux>:

  4010f0: f3 0f 1e fa          endbr64

  4010f4: 80 3d 11 2f 00 00 00 cmpb   $0x0,0x2f11(%rip)        # 40400c <completed.0>

  4010fb: 75 13                jne    401110 <__do_global_dtors_aux+0x20>

  4010fd: 55                   push   %rbp

  4010fe: 48 89 e5             mov    %rsp,%rbp

  401101: e8 7a ff ff ff       call   401080 <deregister_tm_clones>

  401106: c6 05 ff 2e 00 00 01 movb   $0x1,0x2eff(%rip)        # 40400c <completed.0>

  40110d: 5d                   pop    %rbp

  40110e: c3                   ret

  40110f: 90                   nop

  401110: c3                   ret

  401111: 66 66 2e 0f 1f 84 00 data16 cs nopw 0x0(%rax,%rax,1)

  401118: 00 00 00 00 

  40111c: 0f 1f 40 00          nopl   0x0(%rax)


0000000000401120 <frame_dummy>:

  401120: f3 0f 1e fa          endbr64

  401124: eb 8a                jmp    4010b0 <register_tm_clones>


0000000000401126 <main>:

  401126: 55                   push   %rbp

  401127: 48 89 e5             mov    %rsp,%rbp

  40112a: bf 10 20 40 00       mov    $0x402010,%edi

  40112f: b8 00 00 00 00       mov    $0x0,%eax

  401134: e8 f7 fe ff ff       call   401030 <printf@plt>

  401139: b8 00 00 00 00       mov    $0x0,%eax

  40113e: 5d                   pop    %rbp

  40113f: c3                   ret


Disassembly of section .fini:


0000000000401140 <_fini>:

  401140: f3 0f 1e fa          endbr64

  401144: 48 83 ec 08          sub    $0x8,%rsp

  401148: 48 83 c4 08          add    $0x8,%rsp

  40114c: c3                   ret


./hello: This will output a simple message within the hello file

"Hello, world!"

aarch64 Server
In this server, when using the make command, it defines the code to run it successfully such as:

as -g -o hello.o hello.s - GNU Assembler, -g includes debugging information
ld -o hello hello.o - GNU Linker, -o output file name

Down below is the initial code for Hello.s:

.text
.globl _start
_start:
 
        mov     x0, 1           /* file descriptor: 1 is stdout */
        adr     x1, msg         /* message location (memory address) */
        mov     x2, len         /* message length (bytes) */

        mov     x8, 64          /* write is syscall #64 */
        svc     0               /* invoke syscall */
 
        mov     x0, 0           /* status -> 0 */
        mov     x8, 93          /* exit is syscall #93 */
        svc     0               /* invoke syscall */
 
.data
msg:    .ascii      "Hello, world!\n"
len=    . - msg

Modifying message to include the loop index values, showing each digit from 0 to 9:

.text
.globl _start
_start:

        mov     x19, #0         /* Loop counter (starts at 0) */

loop:
        adr     x1, msg         /* Load "Loop: " message address */
        mov     x2, msg_len     
        mov     x0, 1           
        mov     x8, 64         
        svc     0               

        mov     x0, 1           
        adr     x1, num_buf     
        add     x20, x19, #48   /* Convert counter to ASCII */
        strb    w20, [x1]       /* Store ASCII character */
        mov     x2, #1          /* Single character length */
        mov     x8, 64          
        svc     0               

        mov     x0, 1
        adr     x1, nl          /* Load newline character */
        mov     x2, #1          
        mov     x8, 64          
        svc     0             

        add     x19, x19, #1   
        cmp     x19, #10        /* Compare with 10, prints loop until 9*/
        b.lt    loop            /* Loop while x19 < 10 */

        /* Exit program */
        mov     x8, 93         
        mov     x0, 0          
        svc     0               

.data
msg:    .ascii  "Loop: "       
msg_len = . - msg            

num_buf: .byte  '0'           
nl:     .ascii  "\n"          

Output:

Loop: 0

Loop: 1

Loop: 2

Loop: 3

Loop: 4

Loop: 5

Loop: 6

Loop: 7

Loop: 8

Loop: 9



STEP 3 & STEP 4: 

Printing each value as a 2-digit decimal value and suppressing the leading 0 such as printing out 1-9 instead of 01-09. Down below is the updated code:

.text
.globl _start
_start:

        mov     x19, #0        

loop:
        adr     x1, msg        
        mov     x2, msg_len     
        mov     x0, 1           
        mov     x8, 64         
        svc     0               

        /* Convert loop index into two digits */
        mov     x21, x19        
        mov     x22, #10        
        udiv    x20, x21, x22   
        msub    x21, x20, x22, x21 

        add     x20, x20, #48   /* Convert to ASCII */
        adr     x1, num_buf     
        strb    w20, [x1]       /* Store first digit */

        add     x21, x21, #48   
        add     x1, x1, #1      
        strb    w21, [x1]       /* Store second digit */

        adr     x1, num_buf     
        ldrb    w20, [x1]       /* Load first digit */
        cmp     w20, #48        
        b.ne    print_number    
        mov     w20, 32         
        strb    w20, [x1]       /* Store updated first digit */

print_number:
        mov     x0, 1         
        adr     x1, num_buf   
        mov     x2, #2          /* Print two characters */
        mov     x8, 64       
        svc     0              

        mov     x0, 1
        adr     x1, nl         
        mov     x2, #1        
        mov     x8, 64          
        svc     0               

        add     x19, x19, #1  
        cmp     x19, #33       
        b.lt    loop          

        /* Exit program */
        mov     x8, 93         
        mov     x0, 0           
        svc     0               

.data
msg:    .ascii  "Loop: "     
msg_len = . - msg             

num_buf: .ascii  "00"          
nl:     .ascii  "\n"           

Output:

Loop:  0

Loop:  1

Loop:  2

Loop:  3

Loop:  4

Loop:  5

Loop:  6

Loop:  7

Loop:  8

Loop:  9

Loop: 10

Loop: 11

Loop: 12

Loop: 13

Loop: 14

Loop: 15

Loop: 16

Loop: 17

Loop: 18

Loop: 19

Loop: 20

Loop: 21

Loop: 22

Loop: 23

Loop: 24

Loop: 25

Loop: 26

Loop: 27

Loop: 28

Loop: 29

Loop: 30

Loop: 31

Loop: 32



STEP 5:

Printing hexadecimal instead of decimal. Down below is code to complete this step:

.text
.globl _start
_start:

        mov     x19, #0     

loop:
        adr     x1, msg        
        mov     x2, msg_len     
        mov     x0, 1           
        mov     x8, 64          
        svc     0             

        /* Convert loop index into two hexadecimal digits */
        mov     x21, x19        
        mov     x22, #16       
        udiv    x20, x21, x22   
        msub    x21, x20, x22, x21 /* Remainder (low hex digit) */

        cmp     x20, #10
        add     x20, x20, #48   /* Convert 0-9 to ASCII */
        b.lt    store_high
        add     x20, x20, #39   /* Convert A-F to ASCII */

store_high:
        adr     x1, num_buf    
        strb    w20, [x1]   

        cmp     x21, #10
        add     x21, x21, #48   /* Convert 0-9 to ASCII */
        b.lt    store_low
        add     x21, x21, #39   /* Convert A-F to ASCII */

store_low:
        add     x1, x1, #1    
        strb    w21, [x1]      

        mov     x0, 1         
        adr     x1, num_buf    
        mov     x2, #2          
        mov     x8, 64         
        svc     0             

        mov     x0, 1
        adr     x1, nl         
        mov     x2, #1         
        mov     x8, 64         
        svc     0               

        add     x19, x19, #1    /* Increment counter */
        cmp     x19, #33        /* Compare with end value (0x20 in hex) */
        b.lt    loop            /* Loop while x19 < 33 */

        /* Exit program */
        mov     x8, 93        
        mov     x0, 0          
        svc     0               

.data
msg:    .ascii  "Loop: "   
msg_len = . - msg              

num_buf: .ascii  "00"          
nl:     .ascii  "\n"           

Output:

Loop: 00

Loop: 01

Loop: 02

Loop: 03

Loop: 04

Loop: 05

Loop: 06

Loop: 07

Loop: 08

Loop: 09

Loop: 0a

Loop: 0b

Loop: 0c

Loop: 0d

Loop: 0e

Loop: 0f

Loop: 10

Loop: 11

Loop: 12

Loop: 13

Loop: 14

Loop: 15

Loop: 16

Loop: 17

Loop: 18

Loop: 19

Loop: 1a

Loop: 1b

Loop: 1c

Loop: 1d

Loop: 1e

Loop: 1f

Loop: 20


Reflection:


I realized how challenging learning the assembly language compared to high-level languages. I found it extremely difficult to manage every operation and memory accessed. Getting the first two steps to run was already a good progress as it required understanding of each command used. These foundational concepts such as arithmetic and looping are hard to grasp when taking a look under the hood and encouraging myself to think at the machine's level. Despite all this, I still recognize the importance of learning low-level language to understand the ability to have better control over the entire program.

Comments

Popular posts from this blog

BATCH 3 | Project Stage 2, Part 3 - Cloned Functions Comparison and Reflection

BATCH 4 | Clone-Prune Analysis Code Pass On Both Architectures

BATCH 3 | Project Stage 2, Part 1 - Clone-Pruning Analysis Pass