Sunday 2 February 2014

Write a simple program with Assembler language

Assembler Lab

I will write a simple program to show the output below:

1. This is my code for x86_64 processor with explanation:

.text
.globl _start
start = 0                               /* starting value for the loop index */
max = 31                              /* loop exits when loop condition is i<max */
_start:
    mov     $start,%r15          /* loop index */
loop:
        mov     $0,%rdx            /* assign value 0 to rdx (refresh the rdx) */
        mov     %r15,%rax       /* move the loop index to rax (for later divide operation) */
        mov     $10,%r10          /* move value 10 to r10 register */
        div     %r10                   /* divide rax by r10 (10), places quotient into rax, */
                                             /* remainder into rdx, rdx must be zero before this step */
        mov     %rax,%r14       /* move the quotient to r14 */
        mov     %rdx,%r13       /* move the remainder to r13 */
        mov     $'0',%r12          /* assign ascii '0' to r12 */
        cmp     $0,%r14             /* compare the quotient with zero */
        je      skip                      /* skip if equal */
        add     %r12,%r14         /* modify the quotient to become the ascii character, */
                                              /* the character will be put into the msg later */
        movq    $high,%rsi        /* location the quotient will be added into */
        movb    %r14b,(%rsi)    /* move the quotient to msg */
skip:
        add     %r12,%r13         /* modify the remainder to become the ascii character */
        movq    $low,%rsi          /* location the remainder will be added into */
        movb    %r13b,(%rsi)    /* move the remainder to msg */

        movq    $len,%rdx         /* message length */
        movq    $msg,%rsi         /* message location */
        movq    $1,%rdi              /* file descriptor stdout */
        movq    $1,%rax             /* syscall sys_write */
        syscall

    inc     %r15                      /* increment index */
    cmp     $max,%r15           /* see if we're done */
    jne     loop                        /* loop if we're not */
    mov     $0,%rdi                /* exit status */
    mov     $60,%rax              /* syscall sys_exit */
    syscall
.data
msg:    .ascii      "Loop:   \n" /* the content of msg  */
len = . - msg                          /* length of msg */
high = . - 3                            /* define variable high */
low = . - 2                              /* define variable low */



2. I also write codes for aarch64 processor:


.text
.globl _start
_start:
        mov             x28, 0                     /* move 0 to x28, loop index */
loop:
                mov     x27,x28                  /* move x28 to x27 for later use */
                mov     x26,'0'                    /* move ascii '0' to x26 */
                mov     x25,10                    /* move 10 to x25 for division operation */

                udiv    x24, x27, x25           /* x27 (loop index) divides by x25 (10), */

                                                          /* quotient is in the x24 */
                msub    x23, x24, x25, x27  /* (x27 - x24 * x25) will be stored in x23, */

                                                          /*which is the remainder of x27 divides by x25 */
                adr     x20,msg                   /* get the location of msg */
                cmp     x24,0                       /* compare the quotient with 0 */
                beq     skip                         /* go to skip if equal */
                add     x24, x24, x26            /* add x26 to x24,  */

                                                          /* which make the quotient become ascii value */
                strb    w24,[x20,6]               /* move the quotient ascii value to the msg offset 6 */
skip:
                add     x23, x23, x26            /* make the remainder become ascii value */
                strb    w23,[x20,7]               /* move the remainder ascii value to msg offset 7 */

                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     1                               /* invoke syscall */

        add     x28, x28, 1                        /* add 1 to loop index */
        cmp     x28, 31                             /* compare index with 31 */
        bne     loop                                  /* go to loop if not equal */
        mov     x0, 0                                /* status -> 0 */
        mov     x8, 93                              /* exit is syscall #93 */
        svc     0                                       /* invoke syscall */

.data
msg:    .ascii      "Loop:   \n"               /* define msg */
len = . - msg                                        /* length of msg */