Software > Coding
Erste Assembler-Gehversuche
Mado:
Ich hatte gestern ein kleines erstes Programm geschrieben, wo ich eine Assembler-Datei asmmul.s habe, die ich in ein C-Programm einbinden möchte. Die Assembler-Unterroutine soll nichts anderes machen, als zwei WORD-Werte zu einem LONG multiplizieren und dann über D0 wieder an das C-Programm übergeben. Ich erhalte aber ein komisches Ergebnis:
--- Code: ---a x b = 24240
--- Ende Code ---
Vielleicht kann mir ein alter Hase bei meinen Gehversuchen helfen? Hier mein Code:
Makefile:
--- Code: ---# For Linux
CC = m68k-atari-mint-gcc
CFLAGS = -mshort -O2 -Wall
OBJS = main.o asmmul.o
all: asmmul.prg
asmmul.prg: $(OBJS)
$(CC) $(CFLAGS) -o $@ $(OBJS)
main.o: main.c
$(CC) $(CFLAGS) -c $<
asmmul.o: asmmul.s
$(CC) $(CFLAGS) -c $<
--- Ende Code ---
C-Programm main.c:
--- Code: ---#include <stdio.h>
extern long asmmul(int factor, int value);
int main(void) {
int f = 5;
int v = 10;
long ret = 0;
ret = asmmul(f, v);
printf("a x b = %d\n", ret);
return 0;
}
--- Ende Code ---
Und das Assembler-Stückchen assmul.s:
--- Code: --- .text
.global _asmmul
_asmmul:
clr.l d1
clr.l d0
move.w 2(sp),d1
move.w 4(sp),d0
muls d1,d0
rts
.end
--- Ende Code ---
Da ich nur die Scratch-Register D0 und D1 an Registern verwende, save ich keine Register auf dem Stack.
czietz:
Der erste Parameter liegt bei 4(SP) auf dem Stack.
PS: Vorsicht mit -mshort. Die Standard-MiNTLib ist nicht damit compiliert. Eventuell weiß @Thorsten Otto, ob es eine MiNTLib dafür gibt. (libcmini kann man als "mshort"-Version bauen.)
Mado:
Ah, jetzt funktioniert es. So habe ich jetzt den Code angepasst:
--- Code: --- .text
.global _asmmul
_asmmul:
clr.l d1
clr.l d0
move.w 4(sp),d1
move.w 6(sp),d0
muls d1,d0
rts
.end
--- Ende Code ---
Und beim printf im C-Programm muss es natürlich ein long bei der Ausgabe sein:
--- Code: --- printf("a x b = %ld\n", ret);
--- Ende Code ---
Beim Programmieren bin ich momentan komplett nur in TOS unterwegs. Soweit ich es sehen kann, ist im TOS jeder int und auch alle Übergaberegister etc 16 Bit weit. Wenn ich also auf 32 Bit aufbauen würde, müsste ich immer explizit short int (oder WORD???) angeben. Ebenfalls ist es ja so, dass bestimmte Assember-Direktiven in short schneller sind, als in long. Warum wurde dieser Weg gewählt?
czietz:
Die TOS-Bindings sind natürlich in MiNTLib korrekt, d.h. es werden 16-Bit-Worte übergeben, wo dies nötig ist, ohne dass Du explizit "short" dran schreiben müsstest. Generell gilt beim Portieren von Unix-Software (was ja die Stärke der MiNTLib ist), dass das besser funktioniert, wenn ein "int" eben 32 Bit lang ist. (Nicht jede Software ist mit intNN_t und uintNN_t geschrieben.)
Mado:
Ah, ok, verstanden. Ich wurschtel gerade im EmuTOS rum, also nicht im Mint. Das EmuTOS ist ja mit -mshort kompiliert. Ich möchte herausfinden, welche Grafikroutinen sich ggf. durch schnellere Assembler-Routinen ersetzen lassen. Ich komm irgendwie nicht drüber hinweg, dass ich NVDI installiere und teilweise um Faktoren schneller bin.
Ich habe mir mal einige Routinen als Assembly angeschaut und nur die Hände über dem Kopf zusammen geschlagen. Was der C-Compiler da baut, scheint mir nicht die vollen CISC-Features bzw. besonders leistungsfähige Kommandos des Prozessors auszunutzen.
Da ich m68k-Assembler immer nur im ganz kleinen Bereich genutzt habe und das auch schon 25 Jahre her ist, werd ich wohl ein ziemlich langes Weilchen brauchen, bis ich da überhaupt was zustande bringe. Siehst ja. ;-)
Navigation
[0] Themen-Index
[#] Nächste Seite
Zur normalen Ansicht wechseln