top of page

LAB4 ASSEMBLY LANGUAGE PROGRAM X86_64

We will create a program on both platforms x86 and Aarch64 which will loop 30 times printing the number in the index as shown below in the example:


Loop: 00

Loop: 01

Loop: 02

Loop: 03

Loop: 04

Loop: 05

Loop: 06

Loop: 07

Loop: 08

Loop: 09

....

Loop: 29


The twist here is that we will print these numbers using two values generated by dividing the index value by 10. So we will produce a quotient which will be the leading character and a remainder which will be the latter character.


------------------------------------------------------

STARTING WITH THE X86 ARCHITECTURE

------------------------------------------------------


Getting Loop to print the number in the index was fairly simple as we just needed to move the value of the index into a register of its own and then move that register into the memory address of the string we want to append to.

The tricky part here was figuring out we only needed 1 byte instead of the whole 64 which would overwrite the entire message and print garbage.

We also needed to use the "add" command, to add 48 to the byte of the register we were moving into memory so that the compiler can interpret it as ASCII.

Printing the complete list as shown above was a bit more challenging as we had to divide 2 number to get the quotient and the remainder.


--------------------------------

PROBLEMS WITH THE DIV COMMAND

--------------------------------


Now the DIV command in X86 architecture only takes one parameter and the way it works is the parameter it takes is the divisor. And it divides agaisnt whatever value is stored inside the %RAX register.

So we need to move our value of the index into the %RAX register and give the %R12 register the value 10 because 10 is our divisor.

Next before we divide we will need to clear the %RDX register as this is where the remainder will be placed, but it is often filled with garbage because it concatenates with the %RAX register

Once we do this and execute the "div" command and use the quotient in the %RAX register and the remainder in the %RDX register to genrate the above sequence


---------------------------------

SUPRESSING THE TRAILING ZERO CHARACTES

---------------------------------


We don't want the program to print 01 or 02 if there is a leading zero.

To surpress this we will use the "cmp", "jne" commands and a label.

So when we go to compare the quotient to the number 0, if these 2 are NOT EQUAL we will jump to a label which will add the quotient to the memory address of the string, otherwise we will skip over the quotient.


---------------------------------

---------------------------------

FULL CODE ANALYSIS

---------------------------------

---------------------------------


.text

.globl _start


start = 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 $start,%r15 /* loop index */


loop:

mov %r15,%rax // Prepare registers for the div command

mov $10,%r12 // Our divisor

xor %rdx,%rdx // Set rdx to zero


div %r12 // divide the divsor by the value in %RAX

add $48,%rdx // Need to add 48 so that the buffer can read in ASCII

mov %dl,msg+6 // Move the value of the one byte in register %RDX to the memory location


cmp $0,%al // Compare to see if there is a zero

jne label // jump to the label if there is no zero

call printer // if there is a zero we will jump to the label printer


label:

mov %al,%r11b // Like above we will append the quotient to the msg memory address

add $48,%r11b

mov %r11b,msg+5

call printer


printer: // Print the message

mov $len,%rdx

mov $msg,%rsi

mov $1,%rdi

mov $1,%rax

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


6 views0 comments

Recent Posts

See All

Closing Thoughts

For my final blog post I would like to discuss what I have learned and plan to utilize in the future from this course. So although I was not able to successfully improve my package to operate function

Stage 3 Optimization(COMPUTER ARCHITECTURE ENDIANESS)

Seeing as how the compiler flags did not provide any optimization I will on to my next attempt which is converting big endian to small endian. The aarch64 architecture uses the little endian byte orde

Stage 3 Optimization(Compiler Flags)

My first attempt to optimize the project will be to work with the compiler flag options. By default the compiler is set to compile in this manner "gcc -E -g -o2" The -E option represents preprocesses

bottom of page