======COMPORG COURSE NOTES======
{{ :notes:asm.jpg |}}
=====Useful links=====
* [[http://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/|System Calls]]
* [[https://callumscode.com/blog/2010/jan/x86-64-linux-syscalls|64-bit Linux Syscalls]]
* [[https://software.intel.com/en-us/articles/introduction-to-x64-assembly|Intel Introduction to x64 Assembly]]
* [[https://wiki.cdot.senecacollege.ca/wiki/X86_64_Register_and_Instruction_Quick_Start|X86 64 Register and Instruction Quick Start]]
* [[http://www.felixcloutier.com/x86/index.html|x86 and amd64 instruction reference]]
* [[https://en.wikipedia.org/wiki/CORDIC|CORDIC]]
* [[http://unixwiz.net/techtips/x86-jumps.html|More info on jumps]]
* https://www.youtube.com/watch?v=XuUD0WQ9kaE
* [[https://www.tortall.net/projects/yasm/manual/html/objfmt-elf64.html]]
* [[https://systemoverlord.com/2017/03/19/got-and-plt-for-pwning.html]]
* ARM assembly
* [[http://www.microdigitaled.com/ARM/ASM_ARM/Software/ARM_Assembly_Programming_Using_Raspberry_Pi_GUI.pdf]]
* [[http://bob.cs.sonoma.edu/]]
* [[http://www.peter-cockerell.net/aalp/html/frames.html]]
* http://users.ece.utexas.edu/~valvano/EE345M/Arm_EE382N_4.pdf
* http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.aeg0014g/index.html
* [[https://w3challs.com/syscalls/?arch=arm_strong|Linux/arm32le System Calls]]
* [[http://infocenter.arm.com/help/topic/com.arm.doc.qrc0001l/QRC0001_UAL.pdf|ARM assembly cheat sheet]]
* [[https://www.scss.tcd.ie/~waldroj/3d1/arm_arm.pdf|ARM reference manual]]
* [[https://raspberrypiassembly.wordpress.com/2013/03/30/hello-arm/|Hello World]]
* http://www.keil.com/support/man/docs/armasm/armasm_dom1359731145503.htm
=====January 18th 2018=====
This class we went over the specifications for our project PNC0!!
This project and it's specifications can be found here:
* [[http://lab46.corning-cc.edu/notes/comporg/projects/pnc0#program_specifications]]
Almost all of this was written by the students of the class. Good job everyone the project page is top notch.
We also were given an opportunity to get a lil bit of a head start for anyone who can't contain their excitement for this course. We were shown how to convert our c programs into assembly code:
Turn your C code into assembly
$ gcc --std=c99 -Wall -S program program.c
For those of us who weren't taking any of our saviors classes last semester there was an aaaammmmazzzziinnggg paper on printf:
A cool paper on the **printf** function 1/18/2018- COMPORG \\
**[[/_media/haas/printf.pdf|printf paper]]** \\
=====January 23rd 2018=====
So guys today we decided to make our very first program in assembly. Our first program was the "Hello, World!" program.
So in your desired directory for this program go ahead and make a file with a **.asm** extension and the file should be as follows.
section .data
message db "Hello, World!", 10
section .text
global _start
_start:
mov rax, 1
mov rdi, 1
mov rsi, message
mov rdx, 14
syscall
mov rax, 60
mov rdi, 0
syscall
Now you have to go through steps in order to compile assembly, first you need to run it through an assembler **nasm**
$ nasm -f elf64 -o (desired filename).o (source code).asm
now you will have the assembled version of your code, but you still need to link it so use **ld** for that.
$ ld -o (desired filename) (assembled filename).o
Then your program should be all ready! **./filename** and witness your Hello, World!
=====January 25th 2018=====
Alright, so for this class we went through the program that we wrote last class, and started to explain how it worked. There were also some useful links that were shared in order to help learn assembly (it was also sent to the mailing list).
[[https://software.intel.com/en-us/articles/introduction-to-x64-assembly]]
There was another link that was sent out on assembly which wasn't sent in the mailing list, but was sent in the irc, in case you missed it.
[[
https://wiki.cdot.senecacollege.ca/wiki/X86_64_Register_and_Instruction_Quick_Start]]
=====January 30th 2018=====
Since we are still learning how to program in assembly today in class we went over the link that was shared last class.
[[https://software.intel.com/en-us/articles/introduction-to-x64-assembly]]
Make sure to read this link. It helps to be in class, but those of you who aren't in class... Thee wedge was kind enough to draw everyone a picture as to how the different register regions are (in the link the paragraph below figure 1)
{{:notes:intel_example_figure_1.jpg?400|}}
In case you can't find the section of where this is taking place:
RAX, RBX, RCX, RDX, RBP, RSI, RDI, and RSP. The second eight are named R8-R15. By replacing the initial R with an E on the first eight registers, it is possible to access the lower 32 bits (EAX for RAX). Similarly, for RAX, RBX, RCX, and RDX, access to the lower 16 bits is possible by removing the initial R (AX for RAX), and the lower byte of the these by switching the X for L (AL for AX), and the higher byte of the low 16 bits using an H (AH for AX).
=====February 1st 2018=====
So today in class we mainly went over how to use gdb with assembly. There was a message sent out to the mailing list that shows how to use it in more detail, however I will explain some of the basics.
So to run gdb do:
* gdb ./programName
* break _start
* layout asm
* set disassembly-flavor intel
* run
To progress one step at a time type: **ni**
Now to see the registers go a head and do:
(gdb) display/x $register
for every register that you want. (replace register with the register name)
To know what registers you are using you can type: **info registers**
and all of the registers will display.
=====February 6th 2018=====
This class we went over moar of the assembly for Intel. The links that we went over were sent to the mailing list. Really for days like these it does help that you are in class, because we have been going over essential information for the class.
Just in case you don't want to go to your gmail...
[[http://www.felixcloutier.com/x86/index.xml]]
This is the link that we went over in class.
=====February 13th 2018=====
Today in class we continued on our adventure in sof0.asm.
So this program that we are writing in assembly will be able to square numbers double digits numbers that end in 5 (ex. 25^2 = (n(n+1)) + 5^2 = (2(2+1)) + 25 = (6) + 25 = 625). So note there are two separate programs of sof0. This is the first one.
section .data
inputmsg db "Enter number: "
junk db " ", 0
number db " ", 0
output db " "
section .text
global _start
_start:
; prompt user to enter a number
; using write syscall (1 in rax)
;
mov rax, 1
mov rdi, 1
mov rsi, inputmsg
mov rdx, 14
syscall
; obtain input from user
; using read syscall (stdin)
;
mov rax, 0
mov rdi, 0
mov rsi, number
mov rdx, 2
syscall
; get rid of the newline
;
mov rax, 0
mov rdi, 0
mov rsi, junk
mov rdx, 1
syscall
; get the one's place value (copy byte from number "array" into register)
;
mov rax, 0
mov al, [number+1]
sub al, 0x30
cmp al, 0x5
jne exit
mov bl, 5
mul bl
mov r8, rax ; save our integer 25 into r8
; get the ten's place value
;
mov rax, 0
mov al, [number+0]
sub al, 0x30
mov bl, al
add bl, 1
mul bl
mov r9, rax ; save our integer into r9
; itoa (convert integers back to ascii)
;
mov bl, 10
div bl
mov cl, ah ; copy remainder into c register
and ax, 0x00FF ; preserve just the quotient
add al, 0x30 ; ASCII-ify our integer value
mov [output+0], al ; place it in our memory
add cl, 0x30 ; ASCII-ify our remainder value
mov [output+1], cl ; place it in our memory
mov rax, r8 ; copy 25 into A register
mov bl, 10 ; set up for division
div bl ; divide
mov cl, ah ; save remainder (5)
and ax, 0x00FF ; mask it
add al, 0x30 ; ASCII-ify the 2
mov [output+2], al ; store it
add cl, 0x30 ; ASCII-ify 5
mov [output+3], cl ; store it
mov rax, 10 ; place a 10 (ASCII newline) in A reg
mov [output+4], al ; pad newline onto our ASCII string
; display answer (in output) to STDOUT via write syscall
mov rax, 1
mov rdi, 1
mov rsi, output
mov rdx, 5
syscall
; return (0)
exit:
mov rax, 60
mov rdi, 0
syscall
=====February 15th 2018=====
This class we made modifications to our sof program, as well as made our atoi function.
Here is sof1.asm
section .data
inputmsg db "Enter number: "
junk db " ", 0
number db " ", 0
output db " "
section .text
global _start
_start:
; prompt user to enter a number
; using write syscall (1 in rax)
;
mov rax, 1
mov rdi, 1
mov rsi, inputmsg
mov rdx, 14
syscall
; obtain input from user
; using read syscall (stdin)
;
mov rax, 0
mov rdi, 0
mov rsi, number
mov rdx, 2
syscall
; get rid of the newline
;
mov rax, 0
mov rdi, 0
mov rsi, junk
mov rdx, 1
syscall
; get the one's place value (copy byte from number "array" into register)
;
mov rax, 0
mov al, [number+1]
sub al, 0x30
cmp al, 0x5
jne exit
mov bl, 5
mul bl
mov r8, rax ; save our integer 25 into r8
; get the ten's place value
;
mov rax, 0
mov al, [number+0]
sub al, 0x30
mov bl, al
add bl, 1
mul bl
mov r9, rax ; save our integer into r9
; itoa (convert integers back to ascii)
;
mov bl, 10
div bl
mov cl, ah ; copy remainder into c register
and ax, 0x00FF ; preserve just the quotient
add al, 0x30 ; ASCII-ify our integer value
mov [output+0], al ; place it in our memory
add cl, 0x30 ; ASCII-ify our remainder value
mov [output+1], cl ; place it in our memory
mov rax, r8 ; copy 25 into A register
mov bl, 10 ; set up for division
div bl ; divide
mov cl, ah ; save remainder (5)
and ax, 0x00FF ; mask it
add al, 0x30 ; ASCII-ify the 2
mov [output+2], al ; store it
add cl, 0x30 ; ASCII-ify 5
mov [output+3], cl ; store it
mov rax, 10 ; place a 10 (ASCII newline) in A reg
mov [output+4], al ; pad newline onto our ASCII string
; display answer (in output) to STDOUT via write syscall
mov rax, 1
mov rdi, 1
mov rsi, output
mov rdx, 5
syscall
; return (0)
exit:
mov rax, 60
mov rdi, 0
syscall
Just in case you were curious, here is the code above, but written in c.
#include
#include
int main()
{
char number[3];
unsigned int input = 0;
int place = 10;
int value = 0;
int result = 0;
fprintf (stdout, "Enter number: ");
fscanf (stdin, "%u", &input);
value = input / place;
result = input - (place * value);
number[0] = value + 0x30;
number[1] = result + 0x30;
number[2] = '\0';
fprintf (stdout, "number[0]: '%c'\n", number[0]);
fprintf (stdout, "number[1]: '%c'\n", number[1]);
fprintf (stdout, "number: %s\n", number);
return (0);
}
Much shorter isn't it.
=====February 27th 2018=====
Break week is over! Thanks wedge for allowing us to take a week off :P.
Alright, so it's the first day back, and we decided to go moar into detail with how to deal with command line arguments. So it's actually pretty easy! It is stored in a stack, so all you have to do is:
pop (specified register)
We also started to go over cordic (which is what is needed to do sqrt) moar information on that can be found here:
[[https://en.wikipedia.org/wiki/CORDIC]]
=====March 1st 2018=====
Alright so as the deadline for pnc3 is on it's way... So today in class we made a get time of day in assembly.
The code as follows:
; NASM program to use the gettimeofday system call
; for fun and profit (and extreme pnc3 goodness)_
;
section .bss
mytime resb 8 ; struct timeval *tv
;section:.data
global _start
section .text
_start:
; gettimeofday(mytime, mytz);
mov rax, 96 ; specify syscall #96 (gettimeofday)
mov rdi, mytime
mov rsi, 0
syscall
nop
nop
;return (0);
mov rax, 60
mov rdi, 0
syscall
We also went over the benefits to cordic VS the math library. To which we wrote a c program to calculate the difference between the time it took to do each square root. The program as follows:
#include
#include
#include
#include
#include "cordic.h"
int main ()
{
double x = 37;
double y = 0.0;
double z = 0.0;
struct timeval time1;
struct timeval time2;
struct timeval time3;
struct timeval time4;
gettimeofday(&time1,0);
y = sqrt_cordic(x,64);
gettimeofday(&time2,0);
gettimeofday(&time3,0);
z = sqrt (x);
gettimeofday(&time4,0);
fprintf(stdout, "cordic sqrt: %lf\n",y);
fprintf(stdout, "cordic time: %8.4lf\n", time2.tv_sec - time1.tv_sec + ((t ime2.tv_usec - time1.tv_usec) / 1000000.0));
fprintf(stdout, "math.h sqrt: %lf\n",z);
fprintf(stdout, "cordic time: %8.4lf\n", time4.tv_sec - time3.tv_sec + ((t ime4.tv_usec - time3.tv_usec) / 1000000.0));
return (0);
}
The math library is faster (hence why it's used in c).
=====March 6th 2018=====
Alright so one moar day until pnc3 done.
So there was a question in class which was how does one do atoi in assembly??
To which we wrote a c program that has given us a better insight into how to do it in assembly. The program is in the public directory, however if you don't want to check there here ya go:
#include
#include
#include
int lenstr(char *); //length of string
int stoi (char *);
int main (int argc, char **argv)
{
fprintf(stdout, "strlen: argv1 is %u chars long\n", strlen(argv[1]));
fprintf(stdout, "lenstr: argv1 is %u chars long\n", lenstr(argv[1]));
fprintf(stdout, "atoi %d\n", atoi(argv[1]));
fprintf(stdout, "stoi %d\n", stoi(argv[1]));
return(0);
}
int lenstr (char *string)
{
int count = 0;
while(string[count] != '\0')
{
count++;
}
return(count);
}
int stoi (char *string)
{
int place = 1;
int index = 0;
int value = 0;
for ( index = (lenstr (string) - 1); index >= 0; index--)
{
value = value + ((string[index] - '0') * place);
place = place * 10;
}
return(value);
}
=====March 8th 2018=====
Alright so it is a Thursday and pnc3's due date was extended. So with that being said everyone noticed that there were some walls when trying do the assignment... So this class was dedicated to answering our questions! There was a few questions, one of which was loops so we went and made a noice program to explain loops.
global _start
section .text
_start:
mov rax, 1
top:
cmp rax, 10
je endloop
inc rax
jmp top
endloop:
bottom:
dec rax
cmp rax, 0
jnz bottom
; return (0)
mov rax, 60
mov rdi, 0
Another question asked in class was a question related to the stack, with that being said we went over stacks, and some great things were learned. It really helps that you are in class to learn this along with us. Here is the code we came up with.
global _start
section .bss
mystack resb 100
section .text
_start:
mov rax, 1
push rax
mov rax, 2
push rax
; Stack exchange
mov r10, rsp ; save stack pointer
mov rsp, mystack ; load our custom stack's address into rsp.
mov rax, 3
push rax
mov rax, 4
push rax
; Stack exchange
mov r11, rsp ; save stack pointer into data register r10
mov rsp, r10 ; load our custom stack's address into rsp.
pop rbx
pop rbx
pop rbx
mov r10, rsp ; save stack pointer
mov rsp, r11 ; load our custom stack's address into rsp.
pop rbx
pop rbx
;exits program
mov rax, 60
mov rdi, 0
syscall
=====March 13, 2018=====
Not much of a turnout this class, so we started later than usual. Today however we looked into how to run c functions in assembly. We had trouble at first, but we figured it out with much exploring and learning in the process.
;assembly program that calls upon the C library's atoi() function
;
extern atoi
extern puts
section .data
mystring: db "47",0
section .text
global _start
_start:
push rbp
mov rdi, mystring
call puts wrt ..plt
pop rbp
mov rax, 60
mov rsi, 0
syscall
This will print "47" on the command line.
To compile this do:
nasm -f elf64 -o programName.o programName.asm
gcc -nostartfiles -o programName programName.o
Special symbols and WRT: https://www.tortall.net/projects/yasm/manual/html/objfmt-elf64.html
=====March 15th, 2018=====
Alright so since this day was a Thursday and Pnc3 was due on Wednesday we decided that comparing the C version against the assembly would be interesting. So with that a journey was on it's way... We ran into multiple problems with peoples primereg (assembly version). We went through multiple peoples code and fixed these problems. If you weren't here you were missing out it was really fun. This is also when we mentioned that Pnc4 would be due on Wednesday and this time we would be implementing primeregba :D.
=====March 20th, 2018=====
Alright guys!! Welcome back to yet another week! So for some reason most of you haven't been coming to class :/. Luckily I am keeping log of what we have done so you guys don't get behind <3. So today we decided that we would go over time again, but a little moar in depth this time. Here is the code that we ended up with.
; NASM program to use the gettimeofday system call
; for fun and profit (and extreme pnc3 goodness)
;
section .bss
mytime resb 16 ; struct timeval *tv
mydelay resb 16 ; struct timeval *tv
mytime2 resb 16 ; struct timeval *tv
;section .data
global _start
section .text
_start:
; gettimeofday(mytime, mytz);
mov rax, 96 ; specify syscall #96 (gettimeofday)
mov rdi, mytime
mov rsi, 0
syscall
mov rbx, 0
mov rcx, 11
mov rax, mydelay
mov [rax], rcx
inc rax
mov [rax], rbx
inc rax
mov [rax], rbx
inc rax
mov [rax], rbx
nop
; sys_nanosleep (syscall 35, struct timespec *, 0)
mov rax, 35 ; specify syscall #96 (gettimeofday)
mov rdi, mydelay
mov rsi, 0
syscall
nop
; gettimeofday(mytime, mytz);
mov rax, 96 ; specify syscall #96 (gettimeofday)
mov rdi, mytime2
mov rsi, 0
syscall
mov rbx, [mytime]
mov rax, [mytime2]
sub rax, rbx
mov rcx, rax ; rcx will contain our seconds
mov rbx, [mytime+8]
mov rax, [mytime2+8]
sub rax, rbx
reflect:
nop
; return (0);
mov rax, 60
mov rdi, 0
syscall
So the almighty wedge has asked for an explanation of this code so if anyone reading this will be able to understand what it's doing. So I'm going to assume that you guys understand what's happening up to "_start:".
So the first thing that we do is do a system call of get time of day (A system call is the same thing that we do when printing something to the screen, and has mmmannyy moar uses :D such as the get time of day call). This is the part of the code.
; gettimeofday(mytime, mytz);
mov rax, 96 ; specify syscall #96 (gettimeofday)
mov rdi, mytime
mov rsi, 0
syscall
So one thing to note here is that we are moving mytime into rdi, now why might we do that? Well mytime has a resb of 16 which means that mytime can effectively store 16 bytes (struct). This is how the get time of day works in c... very similar...
So the next thing to explain to you guys who missed class would be why we did:
mov rbx, 0
mov rcx, 11
mov rax, mydelay
mov [rax], rcx
inc rax
mov [rax], rbx
inc rax
mov [rax], rbx
inc rax
mov [rax], rbx
So the first thing we did here was move 0 into the rbx register, because you can't move a number value to a point in memory (pointer) it has to be another register, same thing for the rcx. So Then we move the struct into rax (holds up to 16 bytes). With that we are then going to add 11 into the first byte (this is for an 11 second time delay). So then We increment rax so we may go to the next byte in the struct we then place a 0 into the next 3 bytes (for a total of 4 bytes in the struct being used). We do this because the get time of day sys call is expecting 4 bytes.
Next we do a nanosleep sys call (this will sleep for 11 seconds because of the struct value):
;sysnanosleep
mov rax, 35 ; specify syscall #96 (gettimeofday)
mov rdi, mydelay
mov rsi, 0
syscall
Next we are going to do another get time of day syscall this is for the ending value (mytime2):
; gettimeofday(mytime, mytz);
mov rax, 96 ; specify syscall #96 (gettimeofday)
mov rdi, mytime2
mov rsi, 0
syscall
Next we want to get the actual run time of our program, so we take registers (we used rbx and rax) and set them equal to the pointer of the struct. We then we effectively did mytime2 - mytime. With this we now have the seconds, so now we moved that value into rcx.
mov rbx, [mytime]
mov rax, [mytime2]
sub rax, rbx
mov rcx, rax ; rcx will contain our seconds
Now you might be wondering "Well how do we get milliseconds?". To which the answer is that we already have it. Turns out that the syscall stores it with an offset (further within the struct). So we just need to access the memory and do mytime2 - mytime, and just like that we have now have how many milliseconds our program ran for.
mov rbx, [mytime+8]
mov rax, [mytime2+8]
sub rax, rbx
Then we do the classic exit the program.
; return (0);
mov rax, 60
mov rdi, 0
syscall
=====March 22nd, 2018=====
Yo yo yo! So welcome back to another Thursday! So primeregba in assembly was due on Wednesday so hopefully you have turned it in :). Anyway today in class we have decided to move on to start making assembly programs using ARM Assembly. So it so happens to be that wedge has set up a raspberry pi 3 on lab46, to access this simply do
ssh pi3b
and just like that you are on the pi! SOOO in class we went over the differences between the two assembly's (because assembly isn't the same on all computers). So it is recommended to start looking at some of the links that in the "Useful links" section under "ARM assembly". So far there wasn't anything assigned due for next class besides looking at the links provided, and if anyone is interested there is a need for a list of the 32 bit system calls for ARM assembly, so if you find something along those lines go ahead and slap her under the "Useful links".
=====March 27th, 2018=====
From what I was told today in class we went over some of the links that we have accumulated over the time off from our last class. These links are on the notes page at the top, and are about arm assembly, and there are some really good links on the arm assembly.
=====March 29th, 2018=====
Alright so for this class we finished a hello world program.
############################################################
#
# Defining where the start should be.
#
.global _start
############################################################
#
# Start of the program.
#
_start:
mov r7, #4 /*saying that we want to write information to the screen (stdout)*/
mov r0, #1 /*output to the monitor(sys_write)*/
ldr r8, =len
mov r2, %r8
ldr r1, =helloworld /*Telling arm to print fromi the helloWorld lable*/
swi 0 /*syscall*/
mov r7, #1 /*sys_exit*/
mov r0, #2 /*returns a 2 for the value*/
swi 0
.data
helloworld:
.asciz "Hello, World! I luve u bb\n"
len = . - helloworld
If you have any questions then you should ask in class (you will get participation points if you do!).
=====April 10th, 2018=====
Alright almost everyone was here during class today! It's been a while since that has happened. Today in class we decided to figure out where the values of argv is stored, and surprise surprise! it's in the stack, just like in our Intel journey.In order to pop from the stack what you have to do is:
pop {register}
Now keep in mind that this is still a pointer to the memory address containing the values.
=====April 12th, 2018=====
This class we explored through different websites...
The link is here: [[http://www.keil.com/support/man/docs/armasm/armasm_dom1359731145503.htm]]
We then navigated through the "Related concepts" a few times, and went through the logic.