Sunday, January 31, 2016

Lab 3 - Code Building

Time to write some assembly! We did this lab in groups so we could put our heads together to write some good assembly code.

First of all we had to download the examples to our directories on the servers and unpack them. This was done with the tar and make command.
Once we had the example files we could take a look at the differences between dumping the C file and the assembler file. When dumping the c source code you get a bunch of information about all the source code. When dumping the assembler code you only get the instructions.

Now it was time to make our own little program. We needed to make a simple looper that goes from 0-9 and prints out the number.
After making our own file with the simple Hello World looper we needed to compile the assembler code using the following commands:
       Run the assembler: as -g -o test.o test.s
       Run the linker: ls -o test test.o
You're going to use these command a lot so it's easier to write it in one command and re-use it.
       as -g -o test.o test.s; ls -o test test.o; ./test

If you do not have the right permissions, use the following command:
       chmod 700 filename

Now to edit some assembler code. 
To print a number in assembler you need to work with ASCII codes. In our case we needed to add 48 to the number because this is the character for 0. We added this offset to an empty register that would not get trampled at the start of the program. In the loop itself we added the offset to the number it's supposed to be (0-9) and set the result in the rsi register. This is the message location register. 
In theory this was supposed to work, but we made a little mistake in the .data section. We set it to be .rodata, this means it was read-only. After changing this to .data it did print all the numbers, but we also had a newline character in our string but that did not seem to work. Appearently the mov command moves the full 64 bytes, even if you only have 1 byte of data. This caused the number to overwrite the newline character. This was an easy fix by adding the b suffix to mov and the register you move it from. 

The next step was to loop from 00-30. 
To get this to work we divided the loop number by 10 and kept track of our remainders. To do this you use the div command, this takes the rax register and divides it by a chosen register. It stored the outcome into rax and the remainder into rdx. The rdx register has to be set to 0 before you use the div command. As before we added our offset of 48 to rax and rdx and moved these into the string.

The last step was to supress the first zero when the number is below 10.
We did this by checking if the quotient was zero. If it was, we used the je(jump if equal) command to jump to a label. This label would be after the mov command to move the first digit to the string, so the first digit would not get printed if the jump occurred.

No comments:

Post a Comment