Lab3 - x86_64

Instruction

In this lab, I explored assembly language programming on both x86_64 and Aarch64 platforms. The objective was to understand the differences in assembly code generation between these architectures and to implement a simple loop in assembly for both platforms. 

Connect x86_64 server.

ssh username@x86-001.spo600.cdot.systems // replace username

Unpack example code.

once you connect to the server, unpack the example code with below command.

tar -xzvf spo600-assembler-lab-examples.tgz


Tree of spo600 directory

sshin36@x86-001:~$ tree spo600

spo600

└── examples

    └── hello

        ├── assembler

        │   ├── aarch64

        │   │   ├── hello.s

        │   │   └── Makefile

        │   ├── Makefile

        │   └── x86_64

        │       ├── hello-gas.s

        │       ├── hello-nasm.s

        │       └── Makefile

        └── c

            ├── hello2.c

            ├── hello3.c

            ├── hello.c

            └── Makefile


Tasks

Task 1: Reviewing Assembly Language Programs

We used objdump -d to disassemble the compiled binaries and compared the output to the original source code. This helped us understand how the source code translates into machine instructions for both x86_64 and Aarch64 architectures.

For example, after compiling hello.c:

gcc -g -O0 -fno-builtin -o hello hello.c

I disassembled the binary:

objdump -d hello > hello_x86_64_disassembly.txt

This generated a detailed disassembly of the binary, which we compared with the source code to study the differences in assembly instructions between x86_64 and Aarch64.



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



loop code in x86_64 assembler:

loop:

     cmp     $max, %r10 /* compare r10 (loop index) with 30 */

        jg end_loop        /* if r10 is greater than 30, exit loop */

        

       movq    %r10, %rax /* store the r10 value into rax for division */

        xor     %rdx, %rdx /* clear rdx for division */

        divq    %r9             /* divide rax value by 10 (r9) */

        

       movq    %rax, %r14 /* store the quotient into r14 */

        movq    %rdx, %r15 /* store the remainder into r15 */

        

       add     $'0', %r14 /* add '0' to r14 so the value will be ASCII number character value */

        add     $'0', %r15 /* add '0' to r15 so the value will be ASCII number character value */

        

       movq    $msg+6, %r11    /* the tens digit location within string */

        movb    %r14b, (%r11)   /* store the digit at the location */

        

       movq    $msg+7, %r12    /* the units digit location within string */

        movb    %r15b, (%r12)   /* store the digit at the location */

        

       movq    $len, %rdx /* message length */

        movq    $msg, %rsi /* message location */

        

       movq    $1, %rdi        /* file descriptor stdout */

        movq    $1, %rax        /* syscall sys_write */

        syscall

        

       inc     %r10            /* increment loop index */

        jmp     loop            /* redo the loop subroutine */


end_loop:

movq    $0, %rdi        /* exit status */

        movq    $60, %rax /* syscall sys_exit */

        syscall


.section .data

msg:    .ascii      "Loop:  #\n"

        len = . - msg

min = 1

max = 30

division = 10


Output

sshin36@x86-001:~/spo600/examples/hello/assembler/x86_64$ ./loop

Loop: 01

Loop: 02

Loop: 03

Loop: 04

Loop: 05

Loop: 06

Loop: 07

Loop: 08

Loop: 09

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

Conclusion

This lab demonstrated the differences in assembly language programming between x86_64 and Aarch64 architectures. Writing a loop that prints numbers alongside a message proved to be straightforward in concept but challenging in execution, particularly when formatting the output correctly. The disassembly step provided valuable insights into how high-level code translates into machine instructions on different platforms.

댓글

이 블로그의 인기 게시물

Project stage-3 (testing & reflection)

Understanding SIMD and SVE: Harnessing Parallelism for Enhanced Performance

Lab3 - AArch64