Search
Detailed description:
This program we will use for writing of our programs, compiling them and generating output (object) file for Misp, MipsPipeS and MipsPipeXL simulators. (We shall use only Mips simulator today).
Empty screen after MipsIt starts:
Follow these steps: File → New → Project tab, there select Assembler, fill-in name for the project and select folder for it.
Then continue with File → New → File tab. there select Assembler, fill-in name for your file and check that you have checked “Add to project”
Into newly opened window (with *.s suffix) write your own program:
You can use this template for your code:
#define t0 $8 #define t1 $9 #define t2 $10 #define s0 $16 #define s1 $17 #define s2 $18 .globl start .set noat .ent start start: // TODO: Write your code here. nop .end start
As an example we will try following simple code. It adds two integers stored in registers s0 and s1 and store result into register s2.
addi s0, $0, 0x15 addi s1, $0, 0x45 add s2, s0, s1
Keywords .globl, .data, .text, .word are compiler pseudoinstructions. Detailed description is in (GNU Assembler Manual).
To compile the project use Build XX from Build menu (XX is name of your project). Alternatively you can use F7 key. Three files will be generated with suffix *.o, *.out and *.sreg. These will be placed in Objectsubdirectory in your project. If everything goes right, the Output window in MipsIt should look like following picture:
Object
Output
The Mips program simulates MIPS processor and we will use it to execute our program, investigate what is doing and to debug it.
The first screen after the Mips simulator starts:
Open the compiled file (File → Open). Compiled file has *.out or *.sreg suffix. Open window with values in registers (View → Register) and content of memory (View → Memory).
Now we are ready to go step by step through our code. To go step by step use CPU → Step from main menu or green arrow icon from the toolbar. The result should look as follows:
If any of Mips, MipsPipeS or MipsPipeXL is running, you can load code from the development environment (MipsIT) by clicking on Build → Upload → To Simulator (F5).
This item will also reset the processor into initial state.
In many practical applications we have to use median filter. This median filter removes noise (obvious outliers/dead pixels) from a signal or an image. The median filter takes a neighborhood of a sample (10 samples before and 10 after), finds median value and replaces the sample value with this median. Very similar to this filter is mean filter that replaces the sample value with average value of the nearby samples. The median value is usually calculated by sorting the samples by value and picking the sample in the middle. The sorting algorithm is a cornerstone to median filter implementation. Lets assume we have 21 integers stored in array in memory. The array begins in some given address (e.g. 0x00). On integer occupies one word in the memory. The task is to sort the integers in ascending order. To do this we will implement the bubble sort algorithm. In this algorithm two adjacent values are compared and if they are in wrong order, they are swapped. And this comparisons goes repetitively through array until no swaps are done.
The code for bubble sort is bellow:
int pole[5]={5,3,4,1,2}; int main() { int N = 5,i,j,tmp; for(i=0; i<N; i++) for(j=0; j<N-1-i; j++) if(pole[j+1]<pole[j]) { tmp = pole[j+1]; pole[j+1] = pole[j]; pole[j] = tmp; } return 0; }
Transcribe C code above to MIPS assembler. Verify correctness of your implementation in Mips simulator. We will be using this program in the next class. So finish the program at home, if you have not finished it during the class.
Here is a template, you can use:
#define t0 $8 #define t1 $9 #define t2 $10 #define t3 $11 #define t4 $12 #define s0 $16 #define s1 $17 #define s2 $18 #define s3 $19 .globl array .data .align 2 array: .word 5 3 4 1 2 .text .globl start .ent start start: // TODO: Write your code here nop .end start
if (i ==j) f = g + h; f = f – i;
// s0=f, s1=g, s2=h, s3=i, s4=j bne s3, s4, L1 // If i!=j, go to label L1 add s0, s1, s2 // if block: f=g+h L1: sub s0, s0, s3 // f = f-i
if (i ==j) f = g + h; else f = f – i;
// s0=f, s1=g, s2=h, s3=i, s4=j bne s3, s4, else // If i!=j, go to **else** label add s0, s1, s2 // if block: f=g+h j L2 // jump behind the **else** block else: sub s0, s0, s3 // else block: f = f-i L2:
int pow = 1; int x = 0; while(pow != 128) { pow = pow*2; x = x + 1; }
// s0=pow, s1=x addi s0, $0, 1 // pow = 1 addi s1, $0, 0 // x = 0 addi t0, $0, 128 // t0 = 128 to compare (always have to compare two registers) while: beq s0, t0, done // If pow==128, end the cycle. Go to done label. sll s0, s0, 1 // pow = pow*2 addi s1, s1, 1 // x = x+1 j while done:
int sum = 0; for(int i=0; i!=10; i++) { sum = sum + i; }
//Is equivalent to following while cycle: int sum = 0; int i = 0; while(i!=10){ sum = sum + i; i++; }
// Just as an example... int a, *pa=0x80020040; int b, *pb=0x80020044; int c, *pc=0x00001234; a = *pa; b = *pb; c = *pc;
// s0=pa (Base address), s1=a, s2=b, s3=c lui s0, 0x8002 // pa = 0x80020000; lw s1, 0x40(s0) // a = *pa; lw s2, 0x44(s0) // b = *pb; addi s0, $0, 0x1234 // pc = 0x00001234; lw s3, 0x0(s0) // c = *pc;
int array[4] = { 7, 2, 3, 5 }; int main() { int i,tmp; for(i=0; i<4; i++) { tmp = array[i]; tmp += 1; pole[i] = tmp; } return 0; }
#define s0 $16 #define s1 $17 #define s2 $18 #define s3 $19 .globl array // label "array" is declared as global. It is visible from all files in the project. .data // directive indicating start of the data segment .align 2 // set data alignment to 4 bytes array: // label - name of the memory block .word 7, 2, 3, 5 // values in the array to increment... .text // beginning of the text segment (or code segment) .globl start .ent start start: la s0, array // store address of the "array" to the register s0 addi s1, $0, 0 // initialization instruction of for cycle: i=0, kde i=s1 addi s2, $0, 4 // set the upper bound for cycle for: beq s1, s2, done // if s1 == s2, go to label done and break the cycle lw s3, 0x0(s0) // load value from the array to s3 add s3, s3, 0x1 // increment the s3 register sw s3, 0x0(s0) // replace (store) value from s3 register addi s0, s0, 0x4 // increment offset and move to the other value in the array addi s1, s1, 0x1 // increment number of passes through the cycle (i++). j for // jump to **for** label done: nop .end start
-nostdlib -nodefaultlibs -nostartfiles -Wl,-Ttext,0x80020000
-lm -lgcc -lc
gcc -E assembler.S -o preprocessed_assembler.s