Lab 3

In AArch64, We are trying to get it to print "loop" 10 times:

 .text
 .globl _start
 min = 0                          /* starting value for the loop index; **note that this is a symbol (constant)**, not a variable */
 max = 10                         /* loop exits when the index hits this number (loop condition is i<max) */
 _start:
     mov     x19, min
 loop:
    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 */
     /* ... body of the loop ... do something useful here ... */
     add     x19, x19, 1
     cmp     x19, max
     b.ne    loop
     mov     x0, 0           /* status -> 0 */
     mov     x8, 93          /* exit is syscall #93 */
     svc     0               /* invoke syscall */

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

Now we try to output Loop with the number of time in the loop:


 .text
 .globl _start
 min = 0                          /* starting value for the loop index; **note that this is a symbol (constant)**, not a variable */
 max = 10                         /* loop exits when the index hits this number (loop condition is i<max) */
 _start:
     mov     x19, min
 loop:
    mov     x0, 1           /* file descriptor: 1 is stdout */
    adr     x1, msg       /* message location (memory address) */
    mov     x2, len       /* message length (bytes) */

    /*mov    rbx, 48*/
    add    x3, x19, 48    /* convert int to char */
    adr    x4, msg+6
    strb    w3,[x1,6]    /* writes on byte at the address given */

    mov     x8, 64         /* write is syscall #64 */
    svc     0              /* invoke syscall */
     /* ... body of the loop ... do something useful here ... */
     add     x19, x19, 1
     cmp     x19, max
     b.ne    loop
     mov     x0, 0           /* status -> 0 */
     mov     x8, 93          /* exit is syscall #93 */
     svc     0               /* invoke syscall */

.data
msg:     .ascii      "Loop: #\n" /* msg+7 */
len=     . - msg

Extend the AArch64 code to loop from 00-30, printing each value as a 2-digit decimal number.

  .text
 .globl _start
 min = 0                          /* starting value for the loop index; **note that this is a symbol (constant)**, not a variable */
 max = 30                         /* loop exits when the index hits this number (loop condition is i<max) */
 _start:
     mov     x19, min
 loop:
        mov     x0, 1           /* file descriptor: 1 is stdout */
        adr     x1, msg         /* message location (memory address) */
        mov     x2, len         /* message length (bytes) */

        /*mov   rbx, 48*/
        add     x20, x19, 48    /* convert int to char */
        /*adr   x21, msg+6*/
        mov     x21, #10
        udiv    x22,x19,x21     /* divide by 10 */
        /*msub  x23,x19,x22,x21*/       /*get remainders*/
        msub    x23,x22,x21,x19
        add     x22,x22,48      /*convert*/
        add     x23,x23,48      /*convert*/

        strb    w22,[x1,6]      /* writes on byte at the address given */
        strb    w23,[x1,7]      /* writes on byte at the address given */

        mov     x8, 64          /* write is syscall #64 */
        svc     0               /* invoke syscall */
     /* ... body of the loop ... do something useful here ... */
     add     x19, x19, 1
     cmp     x19, max
     b.ne    loop
     mov     x0, 0           /* status -> 0 */
     mov     x8, 93          /* exit is syscall #93 */
     svc     0               /* invoke syscall */

.data
msg:    .ascii      "Loop: ##\n" /* msg+7 */
len=    . - msg

Change the code as needed to suppress the leading zero (printing 0-30 instead of 00-30). To do this, you'll need to add a conditional into your code (the equivalent of an “if” statement, implemented as a compare followed by a conditional branch or conditional jump). 

  .text
 .globl _start
 min = 0                          /* starting value for the loop index; **note that this is a symbol (constant)**, not a variable */
 max = 30                         /* loop exits when the index hits this number (loop condition is i<max) */
 _start:
     mov     x19, min
 loop:
        mov     x0, 1           /* file descriptor: 1 is stdout */
        adr     x1, msg         /* message location (memory address) */
        mov     x2, len         /* message length (bytes) */

        /*mov   rbx, 48*/
        add     x20, x19, 48    /* convert int to char */
        /*adr   x21, msg+6*/
        mov     x21, #10
        udiv    x22,x19,x21     /* divide by 10 */
        /*msub  x23,x19,x22,x21*/       /*get remainders*/
        msub    x23,x22,x21,x19

        mov     x24,#32
        strb    w24,[x1,6]

        cmp     x22,#0
        b.eq    do_one

        add     x28,x22,48      /*convert*/
        add     x27,x23,48      /*convert*/

        strb    w28,[x1,6]      /* writes on byte at the address given */
        strb    w27,[x1,7]      /* writes on byte at the address given */

        cmp     x23, #0
        b.eq    do_one

do_one:
        add     x23,x23,48
        strb    w23,[x1,7]
        /*ret*/

        mov     x8, 64          /* write is syscall #64 */
        svc     0               /* invoke syscall */
     /* ... body of the loop ... do something useful here ... */
     add     x19, x19, 1
     cmp     x19, max
     b.ne    loop
     mov     x0, 0           /* status -> 0 */
     mov     x8, 93          /* exit is syscall #93 */
     svc     0               /* invoke syscall */

.data
msg:    .ascii      "Loop: ##\n" /* msg+7 */
len=    . - msg

 

In x86_64, We are trying to get it to print "loop" 10 times:

 .text
 .globl    _start
 min = 0                         /* starting value for the loop index; **note that this is a symbol (constant)**, not a variable */
 max = 10                        /* loop exits when the index hits this number (loop condition is i<max) */

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

 loop:

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

        /* ... body of the loop ... do something useful here ... */

        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
.section .data
msg:    .ascii      "Loop\n"
        len = . - msg


Now we try to output Loop with the number of time in the loop:

 .text
 .globl    _start
 min = 0                         /* starting value for the loop index; **note that this is a symbol (constant)**, not a variable */
 max = 10                        /* loop exits when the index hits this number (loop condition is i<max) */

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

 loop:

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

        movq    %r15,%r8
        add     $'0',%r8
        movb    %r8b,msg2

        movq    $len2,%rdx                       /* message length */
        movq    $msg2,%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

.section .data

msg:    .ascii  "Loop: "
        len = . - msg
msg2:   .ascii  "#\n"
        len2 = . - msg2

Extend the x86_64 code to loop from 00-30, printing each value as a 2-digit decimal number.

 .text
 .globl    _start
 min = 0                         /* starting value for the loop index; **note that this is a symbol (constant)**, not a variable */
 max = 30                        /* loop exits when the index hits this number (loop condition is i<max) */

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

 loop:

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

        syscall

        mov     $10,%r10
        movq    $0,%rdx         /*places quotient into rax and remainder into rdx (rdx must be zero before this instruction)*/
        movq    %r15,%rax
        div     %r10

        movq    %rax,%r11
        add     $'0',%r11
        movb    %r11b,msg1

        movq    %rdx,%r12
        add     $'0',%r12
        movb    %r12b,msg2

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

        syscall

        movq    $len2,%rdx                       /* message length */
        movq    $msg2,%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

.section .data

msg:    .ascii  "Loop: "
        len = . - msg
msg1:   .ascii  "#"
        len1 = . - msg1
msg2:   .ascii  "#\n"
        len2 = . - msg2

 

 Change the code as needed to suppress the leading zero (printing 0-30 instead of 00-30).

  .text
 .globl    _start
 min = 0                         /* starting value for the loop index; **note that this is a symbol (constant)**, not a variable */
 max = 30                        /* loop exits when the index hits this number (loop condition is i<max) */

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

 loop:

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

    syscall

    mov    $10,%r10
    movq    $0,%rdx        /*places quotient into rax and remainder into rdx (rdx must be zero before this instruction)*/
    movq    %r15,%rax
    div    %r10


    movq    $' ',%r11
    cmp    $0,%rax

    movb    %r11b,msg1
    je    keep_space

    movq    %rax,%r11
    add    $'0',%r11
    movb    %r11b,msg1

keep_space:

    movq    %rdx,%r12
    add    $'0',%r12
    movb    %r12b,msg2

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

        syscall

        movq    $len2,%rdx                       /* message length */
        movq    $msg2,%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

.section .data

msg:    .ascii    "Loop: "
    len = . - msg
msg1:    .ascii    "#"
    len1 = . - msg1
msg2:    .ascii    "#\n"
    len2 = . - msg2

 

I find this lab also very fun. lots of "what do i do" and "how to i do" moments. but thanks to the quick start quick from professor and google I somehow made the code work. I feel like I could make those code way more efficient in the future with more knowledge of assembly. Right now I am still learn to crawl. Looking forward on the up coming class and labs :)

Comments

Popular posts from this blog

Lab 1

Project Stage 1

Project Stage 2