WOJSKOWA AKADEMIA TECHNICZNA
Architektura i organizacja komputerów II
Sprawozdanie z pracy laboratoryjnej
Nr 3
Student : Adrian Kępa
Grupa : I3X6S1
Nr : 14
Data : 02.04.2014r.
Kod programu
;*********** WINDLX Exp.2: Generate prime number table *************
;*********** (c) 1991 Günther Raidl *************
;*********** Modified 1992 Maziar Khosravipour *************
;-------------------------------------------------------------------
; Program begins at symbol main
; generates a table with the first 'Count' prime numbers from 'Table'
;-------------------------------------------------------------------
.data
;*** size of table
.global Count
Count: .word 6
.global Table
Table: .space Count*4
.text
.global main
main:
;*** Initialization
addi r1,r0,0 ;Index in Table
addi r2,r0,2 ;Current value
;*** Determine, if R2 can be divided by a value in table
NextValue: addi r3,r0,0 ;Helpindex in Table
Loop: seq r4,r1,r3 ;End of Table?
bnez r4,IsPrim ;R2 is a prime number
lw r5,Table(R3)
divu r6,r2,r5
multu r7,r6,r5
subu r8,r2,r7
beqz r8,IsNoPrim
addi r3,r3,4
j Loop
IsPrim: ;*** Write value into Table and increment index
sw Table(r1),r2
addi r1,r1,4
;*** 'Count' reached?
lw r9,Count
srli r10,r1,2
sge r11,r10,r9
bnez r11,Finish
IsNoPrim: ;*** Check next value
addi r2,r2,1 ;increment R2
j NextValue
Finish: ;*** end
trap 0
Program PRIM.S generuje ustaloną ilość liczb pierwszych i wypełnia nimi tablicę. By zmienić ilość wygenerowanych liczb należy zmienić wartość etykiety Count.
Count: .word 6
Program działa następująco:
addi r1,r0,0 ;Index in Table
addi r2,r0,2 ;Current value
Pierwszy rozkaz addi powoduje wpisanie 0 do rejestru R1.
Drugi rozkaz addi powoduje wpisanie 2 do rejestru R2.
NextValue: addi r3,r0,0 ;Helpindex in Table
Kolejnemu rozkazowi addi jest przyporządkowana etykieta NextValue. Ten rozkaz dodawania z argumentem natychmiastowym, spowoduje że w rejestrze R3 znajdzie się 0.
Loop: seq r4,r1,r3 ;End of Table?
bnez r4,IsPrim ;R2 is a prime number
lw r5,Table(R3)
divu r6,r2,r5
multu r7,r6,r5
subu r8,r2,r7
beqz r8,IsNoPrim
addi r3,r3,4
j Loop
Etykieta Loop opisuje szereg kolejnych rozkazów. Rozkaz seq sprawdza czy zawartości rejestrów R1 i R3 są sobie równe, jeśli tak to do rejestru R4 zostanie wpisana 1.
Następnie rozkaz bnez sprawdza czy zawartość rejestru R4 nie jest równa zero. Jeśli nie, to program wykonuje skok do etykiety IsPrim. Jeśli natomiast R4 == 0 to program wykonuje dalsze rozkazy, skok jest nieefektywny.
Rozkaz lw ładuje do rejestru R5 zawartość komórki pamięci TABLE o argumencie w rejestrze R3.
Kolejnym krokiem jest obliczenie dzielenia zawartości rejestru R2 przez zawartość R5 bez znaku, i zapisanie wyniku w rejestrze R6. Następnie rozkaz multu mnoży zawartości R6 i R5 przez siebie bez znaku i zapisuje w rejestrze R7.
Kolejnym rozkazem jest subu czyli odejmowanie bez znaku, w tym rozkazie odejmuje się zawartość rejestru R7 od zawartośći rejestru R2 i wynik zostaje wpisany do rejestru R8. Następnym krokiem jest sprawdzenie czy zawartość R8 jest równa zero. Jeśli tak, to program skacze do miejsca oznaczonego etykietą IsNoPrim a w przeciwnym wypadku, wykonuje dalej instrukcje w pętli Loop.
Dalej za sprawą rozkazu Addi, w rejestrze R3 zostaje zapisana wartość dodawania zawartości rejestru R3 i R4. Na koniec zostaje wykonany skok bezwarunkowy do miejsca oznaczonego etykietą Loop.
IsPrim: ;*** Write value into Table and increment index
sw Table(r1),r2
addi r1,r1,4
;*** 'Count' reached?
lw r9,Count
srli r10,r1,2
sge r11,r10,r9
bnez r11,Finish
W tym fragmencie kodu oznacznym etykietą IsPrim wykonane zostają następujące czynności. Rozkaz sw zapisuje zawartość rejestru R2 do komórki pamięci TABLE od rejestru R1. Następnie rozkaz addi dodaje do zawartości rejestru R1 argument natycmiastowy 4 i zapisuje w rejestrze R1.
Do rejestru R9 zostaje załadowana wartość Count. Następnie wykonane jest przesunięcie logiczne w prawo o 2 miejsca rejestru R1 a wynik tej operacji zostaje wpisany do rejestru R10. Kolejno zostają porównane ze sobą rejestry R10 i R9. Jeśli zawartość R10 jest większa od zawartości R9 to w R11 zostaje wpisana liczba 1. Jeśli R11 nie jest równe zero, to zostaje wykonany skok do etykiety Finish.
IsNoPrim: ;*** Check next value
addi r2,r2,1 ;increment R2
j NextValue
W tym miejscu kodu, wykonywany jest rozkaz addi który zwiększa zawartość rejestru R2 o 1. Następnie wykonuje skok bezwarunkowy do etykiety NextValue.
Finish: ;*** end
trap 0
W tym miejscu jest to koniec działania programu.
Tabela śledzenia
Rozkaz: |
Argumenty: |
Wynik: |
ADDI |
R1, R0, #0 |
R1 = 0 |
ADDI |
R2, R0, #2 |
R2 = 2 |
ADDI |
R3, R0, #0 |
R3 = 0 |
SEQ |
R4, R1, R3 |
R4 = 1 |
BNEZ |
R4, IsPrim |
SKOK EFEKTYWNY |
SW |
Table(R1), R2 |
Table(0) = 2 |
ADDI |
R1, R1, #4 |
R1 = 4 |
LW |
R9, Count |
R9 = 3 |
SRLI |
R10, R1, #2 |
R10 = 1 |
SGE |
R11, R10, R9 |
R11 = 0 |
BNEZ |
R11, Finish |
SKOK NIEEFEKTYWNY |
ADDI |
R2, R2, #1 |
R2 =3 |
J |
NextValue |
SKOK NIEEFEKTYWNY |
ADDI |
R3, R0, #0 |
R3 = 0 |
SEQ |
R4, R1, R3 |
R4 = 0 |
BNEZ |
R4, IsPrim |
SKOK NIEEFEKTYWNY |
LW |
R5, Table(R3) |
R5 = 2 |
DIVU |
R6, R2, R5 |
R6 = 1 |
MULTU |
R7, R6, R5 |
R7 = 2 |
SUBU |
R8, R2, R7 |
R8 = 1 |
BEQZ |
R8, IsNoPrim |
SKOK NIEEFEKTYWNY |
ADDI |
R3, R3, #4 |
R3 = 4 |
J |
Loop |
SKOK EFEKTYWNY |
SEQ |
R4, R1, R3 |
R4 = 1 |
BNEZ |
R4, IsPrim |
SKOK EFEKTYWNY |
SW |
Table(R1), R2 |
Table(4) = 3 |
ADDI |
R1, R1, #4 |
R1 = 8 |
LW |
R9, Count |
R9 = 3 |
SRLI |
R10, R1, #2 |
R10 = 0 |
SGE |
R11, R10, R9 |
R11 = 0 |
BNEZ |
R11, Finish |
SKOK NIEEFEKTYWNY |
ADDI |
R2, R2, #1 |
R2 =4 |
J |
NextValue |
SKOK EFEKTYWNY |
ADDI |
R3, R0, #0 |
R3 = 0 |
SEQ |
R4, R1, R3 |
R4 = 0 |
BNEZ |
R4, IsPrim |
SKOK NIEEFEKTYWNY |
LW |
R5, Table(R3) |
R5 = 2 |
DIVU |
R6, R2, R5 |
R6 = 2 |
MULTU |
R7, R6, R5 |
R7 = 4 |
SUBU |
R8, R2, R7 |
R8 = 0 |
BEQZ |
R8, IsNoPrim |
SKOK EFEKTYWNY |
ADDI |
R2, R2, #1 |
R2 = 5 |
J |
NextValue |
SKOK EFEKTYWNY |
ADDI |
R3, R0, #0 |
R3 = 0 |
SEQ |
R4, R1, R3 |
R4 = 0 |
BNEZ |
R4, IsPrim |
SKOK NIEEFEKTYWNY |
LW |
R5, Table(R3) |
R5 = 2 |
DIVU |
R6, R2, R5 |
R6 = 2 |
MULTU |
R7, R6, R5 |
R7 = 4 |
SUBU |
R8, R2, R7 |
R8 = 1 |
BEQZ |
R8, IsNoPrim |
SKOK NIEEFEKTYWNY |
ADDI |
R3, R3, #4 |
R3 = 4 |
SEQ |
R4, R1, R3 |
R4 = 0 |
BNEZ |
R4, IsPrim |
SKOK NIEEFEKTYWNY |
DIVU |
R6, R2, R5 |
R6 = 2 |
MULTU |
R7, R6, R5 |
R7 = 4 |
SUBU |
R8, R2, R7 |
R8 = 1 |
BEQZ |
R8, IsNoPrim |
SKOK NIEEFEKTYWNY |
ADDI |
R3, R3, #4 |
R3 = 8 |
J |
Loop |
SKOK EFEKTYWNY |
SEQ |
R4, R1, R3 |
R4 = 1 |
BNEZ |
R4, IsPrim |
SKOK EFEKTYWNY |
SW |
Table(R1), R2 |
Table(8) = 5 |
ADDI |
R1, R1, #4 |
R1 = 12 |
LW |
R9, Count |
R9 = 3 |
SRLI |
R10, R1, #2 |
R10 = 3 |
SGE |
R11, R10, R9 |
R11 = 1 |
BNEQ |
R11, Finish |
SKOK EFEKTYWNY |
TRAP |
0 |
KONIEC |
Tabela przedstawia działanie rozkazów dla Count = 3.
Poniżej przedstawiam zawartość rejestrów i pamięci po wykonaniu programu dla Count = 6.
Jak widać, pamięć została wypełniona odpowiednio liczbami pierwszymi 2, 3, 5, 7, 11, 13.