User Tools

Site Tools


notes:comporg:spring2018

COMPORG COURSE NOTES

January 18th 2018

This class we went over the specifications for our project PNC0!! This project and it's specifications can be found here:

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
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.

1
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)

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.

1
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

1
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.

1
#include <stdio.h>
#include <stdlib.h>
 
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:

1
; 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:

1
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/time.h>
#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:

1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
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.

1
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.

1
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.

1
;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.

1
; 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:

1
    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):

1
    ;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):

1
; 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.

1
    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.

1
    mov rbx, [mytime+8]
    mov rax, [mytime2+8]
    sub rax, rbx

Then we do the classic exit the program.

1
; 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.

1
############################################################
#
#       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:

1
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.

notes/comporg/spring2018.txt · Last modified: 2019/01/21 18:21 by wedge