Lab 4 - 64-bit Assembly Language Lab
Now I can find the directory in my home directory. Let's start the lab!
1. Review, build, and run the aarh64 assembly language programs. Take a look at the code using objdump -d objectfile and compare it to the source code.
$ objdump -d hello
hello: file format elf64-littleaarch64
Disassembly of section .text:
00000000004000b0 <_start>:
4000b0: d2800020 mov x0, #0x1 // #1
4000b4: 100800e1 adr x1, 4100d0 <msg>
4000b8: d28001c2 mov x2, #0xe // #14
4000bc: d2800808 mov x8, #0x40 // #64
4000c0: d4000001 svc #0x0
4000c4: d2800000 mov x0, #0x0 // #0
4000c8: d2800ba8 mov x8, #0x5d // #93
4000cc: d4000001 svc #0x0
$ cat 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
2. Fix the code to print a word each time it loops.
.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: /* ... 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 */
.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 */
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" .set len , . - msg
.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: add x18, x19, '0' /* convert binary to digit char */ adr x17, msg+6 /* get a pointer to # position in msg */ strb w18, [x17] /* write one byte only */ 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 */
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" .set len , . - msg
$ objdump -d hello-gas
hello-gas: file format elf64-x86-64
Disassembly of section .text:
0000000000401000 <_start>:
401000: 48 c7 c2 0e 00 00 00 mov $0xe,%rdx
401007: 48 c7 c6 00 20 40 00 mov $0x402000,%rsi
40100e: 48 c7 c7 01 00 00 00 mov $0x1,%rdi
401015: 48 c7 c0 01 00 00 00 mov $0x1,%rax
40101c: 0f 05 syscall
40101e: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
401025: 48 c7 c0 3c 00 00 00 mov $0x3c,%rax
40102c: 0f 05 syscall
$ cat hello-gas.s
/*
This is a 'hello world' program in x86_64 assembler using the
GNU assembler (gas) syntax. Note that this program runs in 64-bit
mode.
CTyler, Seneca College, 2014-01-20
Licensed under GNU GPL v2+
*/
.text
.globl _start
_start:
movq $len,%rdx /* message length */
movq $msg,%rsi /* message location */
movq $1,%rdi /* file descriptor stdout */
movq $1,%rax /* syscall sys_write */
syscall
movq $0,%rdi /* exit status */
movq $60,%rax /* syscall sys_exit */
syscall
.section .data
msg: .ascii "Hello, world!\n"
len = . - msg
.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: /* ... 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
.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 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
.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: mov %r15, %r14 add $'0', %r14 movb %r14b, msg+6 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 .section .data msg: .ascii "Loop: #\n" len = . - msg
4. 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 = 31 /* loop exits when the index hits this number (loop condition is i<max) */ _start: mov x19, min mov x20, 10 loop: udiv x21, x19, x20 msub x22, x20, x21, x19 add x18, x21, '0' adr x17, msg+6 strb w18, [x17] add x18, x22, '0' adr x17, msg+7 strb w18, [x17] 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 */
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: 00\n" .set len , . - msg
4-1. Repeat the step for x86_64.
I improved the code to make it print from 0 to 30..text .globl _start min = 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) */ _start: mov $min,%r15 /* loop index */ mov $10, %r13 /* divisor */ loop: mov $0, %rdx mov %r15, %rax div %r13 mov %rax, %r14 add $'0', %r14 cmp $'0', %r14 movb %r14b, msg+6 mov %rdx, %r14 add $'0', %r14 movb %r14b, msg+7 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 .section .data msg: .ascii "Loop: 00\n" len = . - msg
5. 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 = 31 /* loop exits when the index hits this number (loop condition is i<max) */ _start: mov x19, min mov x20, 10 loop: udiv x21, x19, x20 msub x22, x20, x21, x19 add x18, x21, '0' cmp x18, '0' b.ne single_digit mov x18, ' ' single_digit: adr x17, msg+6 strb w18, [x17] add x18, x22, '0' adr x17, msg+7 strb w18, [x17] 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 */
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: 00\n" .set len , . - msg
5-1. Repeat the step for x86_64.
.text .globl _start min = 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) */ _start: mov $min,%r15 /* loop index */ mov $10, %r13 /* divisor */ loop: mov $0, %rdx mov %r15, %rax div %r13 mov %rax, %r14 add $'0', %r14 cmp $'0', %r14 jne single_digit mov $' ', %r14 single_digit: movb %r14b, msg+6 mov %rdx, %r14 add $'0', %r14 movb %r14b, msg+7 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 .section .data msg: .ascii "Loop: 00\n" len = . - msg
Comments
Post a Comment