Arbeitsbereich Programmiersprachen Foren-Übersicht
Autor Nachricht

<  Archiv WS 2010/2011  ~  fehlerhaftes program?

lamborgotti
Verfasst am: 15 Feb 2011 0:31 Antworten mit Zitat
Anmeldungsdatum: 21.10.2010 Beiträge: 81
Code:

main:
         li $v1,  3
         li $a0,  2
         mul $v0,  $a0, 2
         mul $a0,  $v0, 1
         mul $a1,  $a0, 1
         slt $v0,  $v1, $a1
         beqz $v0,  L0
         move $a0,  $v1
         jal _print
         b L1
L0:
         move $a0,  $a1
         jal _print
L1:
         slt $v0,  $a1, $v1
         beqz $v0,  L2
         li $v0,  44
         mul $a0,  $v0, $a1
         jal _print
         li $v1,  0
         li $a1,  27
         b L3
L2:
         li $a0,  0
         jal _print
L3:
         mul $a0,  $v1, $a1
         jal _print

         .text
         .globl _halloc
_halloc:
         li $v0, 9
         syscall
         j $ra

         .text
         .globl _print
_print:
         li $v0, 1
         syscall
         la $a0, newl
         li $v0, 4
         syscall
         j $ra

         .text
           .globl _error
_error:   
           li $v0, 4         
           la $a0, _error_msg
           syscall           
           li $v0, 10         
           syscall           

         .data
         .align   0
newl:    .asciiz "\n"

         .data
         .align   0
_error_msg:  .asciiz "ERROR
"
"

was stimmt daran nicht?
ich bekomme folgendes:

Zitat:
java.lang.AssertionError: Junk on SPIM output: 'Can't expand data segment by 268500992 bytes to 268632064 bytes'
at kanga.test.KangaToMipsTest.runSpim(KangaToMipsTest.java:164)
at kanga.test.KangaToMipsTest.testInputFile(KangaToMipsTest.java:114)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:24)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:3Cool
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)


bei den anderen programmen bekomme ich den gleichen fehler
Benutzer-Profile anzeigen Private Nachricht senden
konrada
Verfasst am: 15 Feb 2011 8:04 Antworten mit Zitat
Anmeldungsdatum: 19.10.2009 Beiträge: 160 Wohnort: Freiburg
"main" ist eine Prozedur, wird vom Spim-Minimalbetriebssystem aufgerufen und muss returnen. Dein Code läuft einfach hinten raus und führt zufällige Instruktionen aus.
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
lamborgotti
Verfasst am: 15 Feb 2011 11:11 Antworten mit Zitat
Anmeldungsdatum: 21.10.2010 Beiträge: 81
achso, das wusste ich einfach nicht
gibt es noch mehr solcher sachen die man wissen muss?

dann hab ich noch eine frage, mit welchem wert inizialisieren ich stack und framepointer? oder wie?
Benutzer-Profile anzeigen Private Nachricht senden
konrada
Verfasst am: 15 Feb 2011 11:17 Antworten mit Zitat
Anmeldungsdatum: 19.10.2009 Beiträge: 160 Wohnort: Freiburg
Auch in der Hinsicht ist "main" eine ganz normale Prozedur: am Anfang von main enthaelt der Stackpointer eine unbekannte Adresse, die als oberes Ende des Stacks geeignet ist. Der Framepointer enthaelt irgendeinen unbekannten Wert, den der Caller wiederhaben will.

Initialisiert wird $sp vom Minimalbetriebssystem im Spim.
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
lamborgotti
Verfasst am: 15 Feb 2011 11:21 Antworten mit Zitat
Anmeldungsdatum: 21.10.2010 Beiträge: 81
ok, das heisst ich muss mir den framepointer und stackpointer an dem orientieren, was im sp steht und am ende den wert von fp wiederherstellen?
muss ich den sp auch wiederherstellen?
Benutzer-Profile anzeigen Private Nachricht senden
konrada
Verfasst am: 15 Feb 2011 11:22 Antworten mit Zitat
Anmeldungsdatum: 19.10.2009 Beiträge: 160 Wohnort: Freiburg
Ja, den auch.
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
lamborgotti
Verfasst am: 15 Feb 2011 11:25 Antworten mit Zitat
Anmeldungsdatum: 21.10.2010 Beiträge: 81
au man, das sind ja ein paar böse überraschungen

ich verstehe nicht, wann ich b branch und wann ich j jump nehmen soll, die machend doch das selbe, ich dachte zuerst das eine ist ein prozeduraufruf und hat was mit ra zu unt, aber das geht ja mit jal
Benutzer-Profile anzeigen Private Nachricht senden
konrada
Verfasst am: 15 Feb 2011 11:36 Antworten mit Zitat
Anmeldungsdatum: 19.10.2009 Beiträge: 160 Wohnort: Freiburg
Fuer unbedingte Spruenge ist "j" besser, hat 26 Bit Offset in der Instruktion, waehrend b-Instruktionen nur 16 Bit Offset in der Instruktion unterkriegen. Wenn der Offset nicht ausreicht, fuegt der Assembler andere Sprungbefehle ein, ist also nicht unser Problem; trotzdem, j dominiert b.
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
lamborgotti
Verfasst am: 15 Feb 2011 11:51 Antworten mit Zitat
Anmeldungsdatum: 21.10.2010 Beiträge: 81
wir haben ja gar kein addi

darf man das machen, weil laut grammatik ist es möglich:

new AInstStmt(new AOp3Instruction(
new AAddOpcode3(),
new ARegOperand(new ASpRegister()),
new ARegOperand(new ASpRegister()),
new AAddrOperand(new ALabAddrImmed(new ARefLabelExpr(new TIdentifier(stackFrameOffset))))));

oder kann ich "{addr_reg} addr_immed register" nutzen mit dem null-register $zero und der zahl die ich haben will
Benutzer-Profile anzeigen Private Nachricht senden
konrada
Verfasst am: 15 Feb 2011 12:03 Antworten mit Zitat
Anmeldungsdatum: 19.10.2009 Beiträge: 160 Wohnort: Freiburg
Beispiel:
Code:

addu $sp, $sp, 8

ergibt, wenn man es parsen laesst und dann in den Debugger schaut, den AST:
Code:

AInstStmt
- AOp3Instruction
-- AAdduOpcode3
-- ARegOperand
-- ARegOperand
-- AAddrOperand
--- AExprAddrImmed
---- AConstExpr
----- TDecimal
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
lamborgotti
Verfasst am: 15 Feb 2011 12:05 Antworten mit Zitat
Anmeldungsdatum: 21.10.2010 Beiträge: 81
hä, ich weiss grad auch nicht wie ich auf den mit dem label kam, eigentlich meinte ich ja das mit AAddrOperand - AExprAddrImmed - AConstExpr

warum nimmst du addu?
soll ich das auch nehmen?
Benutzer-Profile anzeigen Private Nachricht senden
konrada
Verfasst am: 15 Feb 2011 12:09 Antworten mit Zitat
Anmeldungsdatum: 19.10.2009 Beiträge: 160 Wohnort: Freiburg
Ist in dem Fall ziemlich egal -- nur bei Overflow unterscheidet sich "add" und "addu".
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
lamborgotti
Verfasst am: 15 Feb 2011 12:15 Antworten mit Zitat
Anmeldungsdatum: 21.10.2010 Beiträge: 81
und welches sollen wir für die addition aus minijava nehmen?
Benutzer-Profile anzeigen Private Nachricht senden
konrada
Verfasst am: 15 Feb 2011 12:20 Antworten mit Zitat
Anmeldungsdatum: 19.10.2009 Beiträge: 160 Wohnort: Freiburg
Java erkennt nach JLS3, 4.2.2 keinen Overflow bei Integers; daher wuerde addu (also Addition ohne Ueberlauferkennung) das Ueberflussverhalten von Java genauer wiedergeben als add (das bei Ueberlauf eine Prozessor-Exception wirft). Ich akzeptier aber beides.
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
lamborgotti
Verfasst am: 15 Feb 2011 12:24 Antworten mit Zitat
Anmeldungsdatum: 21.10.2010 Beiträge: 81
gut, dann nehme ich addu
aber bei mul, haben wir das ja gar nicht

warum geht das nicht:

Code:
 sw $ra,  $sp


muss das immer

Code:
 sw $ra,  0($sp)

sein?
Benutzer-Profile anzeigen Private Nachricht senden
konrada
Verfasst am: 15 Feb 2011 12:35 Antworten mit Zitat
Anmeldungsdatum: 19.10.2009 Beiträge: 160 Wohnort: Freiburg
Mul ist ohne Overflow (Hp_AppA, A-53). In der sw-Instruktion ist Platz fuer zwei Register und 16 Bit Offset; ein Offset wird also immer gebraucht und kostet nichts extra.
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen

Beiträge vom vorherigen Thema anzeigen:  

Alle Zeiten sind GMT + 2 Stunden
Seite 1 von 1
Dieses Forum ist gesperrt, du kannst keine Beiträge editieren, schreiben oder beantworten.

Gehe zu:  

Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.