SPO600 Assembler Lab 3

In this lab our instructions were to:

  1. Build and run three C versions of the hello.c program for x86_64 and aarch64.
  2. Modify the code so it prints the loop index values like so:
Loop: 0
Loop: 1
Loop: 2
Loop: 3
Loop: 4
Loop: 5
Loop: 6
Loop: 7
Loop: 8
Loop: 9
  1. Extend the code to loop from 00 – 30, printing each value as a 2-digit decimal number.

This lab was completed with my classmates Josue and Miguel. Writing in assembly was no easy task for us as it took us the entire lab to write the loop which repeated 10 times. We added comments in the assembly code explaining what operation that was happening on each line.

This was the x86_64 assembly code that we wrote for the in-class lab:

.text
.globl    _start

start = 0                       /* starting value for the loop index; note that this is a symbol (constant), not a variable */
max = 31                        /* loop exits when the index hits this number (loop condition is i<max) */
divisor = 10
zero = 48	

_start:
    mov     $start,%r15         /* loop index */

loopmd:

	cmp    $divisor,%r15		/* see if loop index is less than 10 */
	jl     loopsg
	mov    $divisor,%r13		/* moved 10 to r13 */
	mov    %r15,%rax		/* moved r15 to rax */
	mov    $zero,%r14		/* moved 48 to r14*/
	mov    $0,%rdx			/* moved 0 to rdx */

	div    %r13			/* divided rax by r13 (loop index by 10) */
	add    %r14,%rax		/* added r14 to rax (48 to the quotient of the division */
	mov    %rax,%r13		/* moved rax to r13 so I can then move only one byte to msg */
	mov    %r13b,msg+6

	add    %r14,%rdx		/* added r15 to r14 */
	mov    %rdx,%r13		/* moved rdx to r13 so I can then move only one byte to msg */
	mov    %r13b,msg+7		/* added number after 'Loop' */
        mov    $len,%rdx                /* message length */
        mov    $msg,%rsi                /* message location */
        mov    $1,%rdi                  /* file descriptor stdout */
        mov    $1,%rax                  /* syscall sys_write */
        syscall
	jmp    check

loopsg:

	mov    $zero,%r14		/* moved 48 to r14*/
	add    %r15,%r14		/* added r15 to r14 */
	mov    %r14b,msg+7		/* added number after 'Loop' */
        mov    $len,%rdx		/* message length */
        mov    $msg,%rsi		/* message location */
        mov    $1,%rdi			/* file descriptor stdout */
        mov    $1,%rax			/* syscall sys_write */
        syscall
	
check:	
	inc     %r15			/* increment index */
	cmp     $max,%r15		/* see if we're done */
	jne     loopmd			/* loop if we're not */

	mov     $0,%rdi			/* exit status */
	mov     $60,%rax		/* syscall sys_exit */
	syscall

.section .data

        msg:    .ascii      "Loop:    \n"
        len = . - msg

A link to the assembly code above can be found here: https://github.com/naiuhz/spo600/blob/master/lab3/86_64/loop.s

And for the aarch64 assembly code:

.text
.globl    _start

start = 0                       /* starting value for the loop index; note that this is a symbol (constant), not a variable */
max = 31                        /* loop exits when the index hits this number (loop condition is i<max) */
divisor = 10
zero = 48
                                /* note: registers 19-28 are safe */
_start:
    mov     x20,start           /* loop index */

loop:
    mov     x2,len              /* message length syscall args*/
    adr     x1,msg              /* message location syscall args*/

    mov     x28,divisor         /* store 10 (divisor) in x28 */
    udiv    x23,x20,x28         /* divide index (x20) by 10 (x28), store quotient into x23; remainer discarded */
    msub    x24,x23,x28,x20     /* store remainder (x20 - (x23 * x28)) into x24 */

    cmp     x23,0               /* check if quotient is 0 (i.e. single digit index) */
    b.eq    sloop               /* if so, branch to single digit loop */

    /* tens digit */
    add     x23,x23,zero        /* increase x23 (quotient) by 48 i.e. convert to ascii value */
    strb    w23,[x1,6]          /* copy 1 byte of w23 to message 6 bytes offset */

    /* ones digit */
sloop:
    add     x24,x24,zero        /* increase x24 (remainder) by 48 i.e. convert to ascii value */
    strb    w24,[x1,7]          /* copy 1 byte of w24 to message 7 bytes offset */
    mov     x0,1                /* file descriptor stdout syscall args*/
    mov     x8,64               /* syscall number is 8; write is 64 */
    svc     0                   /* perform a syscall */

    /* increment & check for exit */
    add     x20,x20,1           /* increment index */
    mov     x22,max             /* compare x22 and max value */

    cmp     x20,x22             /* see if we're done */
    b.lt    loop                /* branch to loop if less than */

    mov     x0,0                /* exit status */
    mov     x8,93               /* syscall sys_exit */
    svc     0

.section .data
    msg:    .ascii      "Loop:   \n"
    len = . - msg

And that assembly code can be found here: https://github.com/naiuhz/spo600/blob/master/lab3/arm64/loop.s

Leave a comment