1,885
edits
Changes
→Group Lab Tasks
[[Category:SPO600 Labs]][[Category:Assembly Language]]
{{Admon/lab|Purpose of this Lab|In this lab, you will experiment with assembler on the x86_64 and aarch64 platforms.}}
{{Admon/tip|Australia and RedSPO600 Servers|Perform this lab on <code>australia.proximity.on.ca</code> (for x86_64) and red (for aarch64, accessed via port 2222 on <code>iraq.proximity.on.ca</code>).}} == Lab 3 == <!-- ### THIS COMMENTED-OUT SECTION DESCRIBES THE ### CONFIGURATION USED FOR THE WINTER 2014 ### OFFERING OF THE SPO600 COURSE, WHERE THE### AARCH64 WORK WAS DONE IN EMULATION ALONGSIDE### THE X86_64 WORK ON THE INTEL HOST "IRELAND".### IN FALL 2014, AARCH64 HARDWARE WAS AVAILABLE,### AND IRELAND HAD FAILED, SO WE SWITCHED TO### THOSE HOSTS. === Ireland - Configuration === The host ''Ireland'' (ireland.proximity.on.ca) has been set up so that you can use it normally as an x86_64 host, or [[SPO600 aarch64 QEMU on Ireland|use an emulation environment to build and run aarch64 binariesServers]]. The directory <code>~/arm64/spo600/examples</code>, which is also accessible as <code>~/spo600-examples</code>, contains these files: ── hello # 'hello world' example programs ├── assembler │ ├── aarch64 # aarch64 assembler version │ │ ├── hello.s │ │ └── Makefile │ └── x86_64 # (you may use your own x86_64 assembler versions │ ├── hello-gas.s # 64-bit instructions with AT&T/gnu assembler syntax (called 'gas'system if desired, /usr/bin/as) │ ├── hello-nasm.s # 32-bit instructions along with Intel/nasm assembler syntax (/usr/bin/nasm) │ └── Makefile └── c ├── hello2.c # C version using the write(AArch64 server) syscall wrapper ├── hello.c # C version using printf() └── Makefile Throughout this lab, take advantage of ''[[make and Makefiles|make]]'' whenever possible.}}
=== Code Examples ===
The code examples for this lab are available at this link: http://england.proximity.on.cain the file <code>/spo600public/spo600-lab3assembler-lab-examples.tgz Please download this archive to your accounts </code> on Australia and Red, and unpack the archive on both systems. Do all of the work for the x86_64 architecture on Australia, and all of the work on the aarch64 architecture on Red[[SPO600 Servers]].
Unpacking the archive in your home directory will produce the following directory structure:
| `-- Makefile
`-- c # Portable C versions
|-- hello2.c # write() version |-- hello3.c # syscall () wrapper version |-- hello.c # printf () version
`-- Makefile
Throughout this lab, take advantage of ''[[make and Makefiles|make]]'' whenever possible.
=== References Resources ===
* [[Assembler Basics]]
*[[Syscalls]]* [[x86_64 Register and Instruction Quick Start]]** [[aarch64 Register and Instruction Quick Start]]
=== Group Lab Tasks ===
{{Admon/tip|Shortcut|To save lab time '''your group can decide''' to do steps 1. Build and run the C versions of -4 as individual homework after the program for x86_64lab.}}
4. Build and run the three C versions of the program for aarch64. Verify that you can disassemble the object code in the ELF binary using <code>objdump -d '''objectfile'''</code> and take a look at the code. 5. Review, build, and run the aarch64 assembly language programs. Take a look at the code using <code>objdump -d '''objectfile'''</code> and compare it to the source code. 6. Here is a basic loop in x86_64 AArch64 assembler - this loops from 0 to 9, using r15 r19 as the index (loop control) counter:
.text
.globl _start
_start:
mov $startx19,%r15 /* loop index */min
loop:
mov $x0, 0,%rdi /* exit status -> 0 */ mov $60x8,%rax 93 /* exit is syscall sys_exit #93 */ svc 0 /* invoke syscall*/ This code doesn't actually do anything while looping, because the body of the loop is empty. On an AArch64 machine, combine this code with code from the "Hello World" assembley-language example, so that it prints a word each time it loops: Loop Loop Loop Loop Loop Loop Loop Loop Loop Loop
Loop: 0
Loop: 9
{{Admon/tip|Character conversion|In order to print the loop index value, you will need to convert from an integer to digit character. In ASCII/ISO-99598859-1/Unicode UTF-8, the digit characters are in the range 48-57 (0x30-0x39). You will also need to assemble the message to be printed for each line - you can do this by writing the digit into the message buffer before outputting it to stdout, which is probably the best approach, or you can perform a sequence of writes for the thee parts of the message ('Loop: ', number, '\n'). You may want to refer to the manpage for <code>ascii</code>.}} 7. Repeat step 6 for x86_64. For reference, here is the loop code in x86_64 assembler:
8. Extend the AArch64 code to loop from 00-30, printing each value as a 2-digit decimal number.
{{Admon/tip|2-Digit Conversion|You will need to take the loop index and convert it to a 2-digit decimal number by dividing by 10. To do this, use the <code>div</code> instruction, which takes the dividend from rax and the divisor from register supplied as an argument. The quotient will be placed in rax and the remainder will be placed in rdx.}}
9. Repeat step 8 for aarch64x86_64.
=== Deliverables ===
=== Optional Challenge ===
Write a program in aarch64 assembly language to print the times tables from 1-12 ("1 x 1 = 1' " through '"12 x 12 = 144'"). Add a spacer between each table, and use a function/subroutine to format the numbers with leading-zero suppression. The output could look something like this:
1 x 1 = 1
2 x 1 = 2