Hallo zusammen,
ich versuche mir seit ein paar Tagen ein kleines
HelloWorld-Blink-Programm direkt in RISCV-Assembler für den CH32V003 zu
bauen und bekam es erst zum Laufen, als ich Verzögerungsschleifen, die
mit dem Pseudo-Befehl "CALL" aufgerufen wurden, direkt ins Hauptprogramm
eingebaut hatte und somit Unterprogramme vermieden hatte.
Ich habe inzwischen das Problem auf den folgenden "Zwei
Zeilen-Quelltext" reduzieren können, welcher bei mir falsch übersetzt
wird:
1 | Start: CALL Subroutine
|
2 | Subroutine: RET
|
Vorweg: Zum Übersetzen benutze ich das Paket
"xpack-riscv-none-elf-gcc-14.2.0-3", die Version des im Paket
enthaltenen Assemblers ist "GNU assembler (xPack GNU RISC-V Embedded GCC
x86_64) 2.43.1".
Wenn man die beiden Zeilen mittels "riscv-none-elf-as.exe myfile.s"
übersetzt und sich danach das Ergebnis mittels
"riscv-none-elf-objdump.exe -d a.out" anschaut, dann sieht man
folgendes:
1 | a.out: file format elf32-littleriscv
|
2 |
|
3 | Disassembly of section .text:
|
4 |
|
5 | 00000000 <Start>:
|
6 | 0: 00000097 auipc ra,0x0
|
7 | 4: 000080e7 jalr ra # 0 <Start>
|
8 |
|
9 | 00000008 <Subroutine>:
|
10 | 8: 00008067 ret
|
Der CALL-Befehl wird hier in zwei Befehle aufgeteilt (das ist auch noch
in Ordnung), es fehlt jedoch im zweiten Befehl (jalr) der notwendige
Offset, damit auch zum Unterprogramm gesprungen wird.
Richtigerweise sollte meiner Ansicht nach diese Zeile so aussehen:
1 | 4: 008080e7 jalr 8(ra) # 8 <Subroutine>
|
Wenn ich in meinem HelloWorld-Blink-Programm die übersetzten
CALL-Befehle derart patche (also die jalr-Befehle mit dem notwendigen
Offset versehe), dass sie auf das Unterprogramm mit der
Verzögerungsschleife zeigen, dann funktioniert auch alles, so wie es
soll...
Es ist also offensichtlich der CALL-Befehl, der nicht korrekt übersetzt
wird. Aber kann das sein? Ich habe auch ältere Versionen des Assemblers
getestet, es ist überall dasselbe Verhalten.
Fehlt vielleicht hier nur eine Option, die ich dem Assembler mitgeben
muss? Oder habe ich hier wirklich einen Fehler entdeckt? Das kann ich
mir aber bei so einem grundlegenden Befehl nicht vorstellen...
Habt ihr irgendwelche Ideen?
Gruß
Thomas