Archiv verlassen und diese Seite im Standarddesign anzeigen : NASM assembler mit c programm
Hallo,
ich hab assembler bisher nur theoretisch in der vorlesung "gelernt". ich will jetzt assembler selber am pc ausprobieren. da die textausgabe aus assembler nicht so einfach ist, will ich aus einem c programm assembler programme starten und 2 variablen übergeben.
diese will ich in assembler verarbeiten und aus dem C programm wieder ausgeben.
hat mir jemand ein code gerüst das diese aufgabe erledigt? irgendwie kann man im assembler programm mit "enter 0,0" den BP setzen um z.b. mit [bp+8] auf die erste variable auf dem stack zuzugreifen. alles nur theoretisch eghört, googlen bringt mir keine brauchbaren ergebnisse....
del_4901
2008-07-04, 22:27:01
Ich nehm immer sowas: http://de.wikipedia.org/wiki/Inline-Assembler
ich will nicht die at&t syntax, bringt mich nur durcheinander.
wie kann ich aus c ein assemblerprogramm das als .o datei vorliegt einbinden und variablen übergeben?
CoconutKing
2008-07-04, 23:15:25
Hier mal ein Anfang:
#include <stdio.h>
int main(void)
{
//für die Intel Syntax
asm(".intel_syntax noprefix\n");
int a=0;
//ausgabe von a=0
printf("a vor asm: %d \n", a);
//255 in %0 = variable a
asm("mov %0,255" : "=a"(a) );
//ausgabe von a = 255
printf("a nach asm: %d\n",a);
}
mit dem : asm("mov %0,255" : "=a"(a) ); legst du fest, dass a auch eine Ausgabevariable ist. d.h. du kannst sie verändern, ohne dem "=":
asm("mov %0,255" : "a"(a) ); wäre die variable a nur lesbar aus sicht des assembler codes.
RattuS
2008-07-05, 00:19:03
Welcher Begriff mir da spontan einfällt, wäre Shared Memory. Aber in diesem Falle versteh ich nicht recht, warum du mit einem C-Programm kommunizieren willst. Konsolenausgabe kannst du auch direkt über Assembler machen. Das ist, sofern du NASM, MASM (-Makros) und Co. verwendest, mit einer Zeile erledigt.
die zeile wäre wie?
Beispiel:
eax=20
ebx=2
addition von eax,ebx ergebnis soll in edx
ausgabe von edx
del_4901
2008-07-05, 01:01:30
Man braucht dafür kein late Binding, das kann man auch early binden. Das ist nur überall Anders und auch nur für Ausnahmesituationen interessant. Und mir fällt jetzt auch nichts ein (mal angesehen von der "Plattformunabhänigkeit" ... inline ASM kann sehr "eigen" sein) wo es Sinnvoll währe. Ich hab das schonmal gemacht, aber das ist zu lange her.
nimm niemals Inline-ASM, da machst du die Portabilität kaputt. Nasm ist super
und lässt sich einfach in ein C-Programm einbinden. Nur die Parameter-Übergabe ist etwas trickreich.
in Nasm sieht das dann so aus
[BITS 32]
[GLOBAL _fow_cdf22_row_mmx]
[SECTION .text]
ALIGN 16
cdf22_pdst equ 4+8
cdf22_psrc equ 4+8+4
cdf22_size equ 4+8+8
; cdf-22 forward transform
_fow_cdf22_row_mmx:
push esi
push edi
mov esi,[esp+cdf22_psrc]
mov edi,[esp+cdf22_pdst]
mov edx,[esp+cdf22_size]
pxor mm0,mm0
pxor mm1,mm1
pxor mm2,mm2
movd mm0,[esi] ;process first 2
movd mm1,[esi+4]
movd mm2,[esi+8]
movq mm3,mm0
paddd mm0,mm2
psrad mm0,1
psubd mm1,mm0
...
und in GCC die Deklaration so
#ifdef __cplusplus
extern "C" {
#endif
void fow_cdf22_row_mmx(_sint32 *,_sint32 *,int);
#ifdef __cplusplus
}
#endif
:)
RattuS
2008-07-05, 10:28:09
die zeile wäre wie?
Beispiel:
eax=20
ebx=2
addition von eax,ebx ergebnis soll in edx
ausgabe von edx
Unter MASM:
mov edx, 0
mov eax, 20
mov ebx, 2
add edx, eax
add edx, ebx
print str$(edx)
Wenn du die Parameter nicht unbedingt von einem anderen Programm brauchst bzw. manuell einsetzen kannst, bau dir eine spartanische Oberfläche mit Inputs und 'nem Button.
del_4901
2008-07-05, 13:36:57
nimm niemals Inline-ASM, da machst du die Portabilität kaputt.
Kaputt macht man sich damit noch gar nichts. Da macht man sich einfach unterschiedliche Makros für. Wenn man den Weg über NASM geht muss man sich ja auch unterschiedliche makefiles machen. Soviel ASM braucht man meißtens eh nicht. Der große Vorteil von inline ASM ist, das der Compiler das ganze optimieren kann/darf.
Kaputt macht man sich damit noch gar nichts. Da macht man sich einfach unterschiedliche Makros für.
den NASM-Code muss ich nur einmal schreiben, warum sollte ich das
zweimal mit fast komplett anderer Syntax tun. :confused:
Wenn man den Weg über NASM geht muss man sich ja auch unterschiedliche
makefiles machen.
was ist mehr Aufwand?
Soviel ASM braucht man meißtens eh nicht. Der große Vorteil von inline ASM ist,
falsch, du brauchst nicht soviel asm.
das der Compiler das ganze optimieren kann/darf.
wäre mir neu.
aber wenn der compiler mein asm noch verbessern kann, sollte ich asm gleich lassen.
del_4901
2008-07-05, 14:53:57
den NASM-Code muss ich nur einmal schreiben, warum sollte ich das
zweimal mit fast komplett anderer Syntax tun. :confused:
was ist mehr Aufwand?
Da muss man sich einfach vernünftige Makros schreiben, oder man nimmt gleich intrinsics.
wäre mir neu.
aber wenn der compiler mein asm noch verbessern kann, sollte ich asm gleich lassen.
Der Programmierer, welcher besser optimiert als ein Compiler den gibt es nicht mehr. Alles andere ist die pure Arroganz/Selbstüberschätzung. ASM braucht man nur dann wenn es wieder mal neue CPU-Befehle gibt, welche der Compiler noch nicht kennt/anwenden kann. Oder man Strukturen/Verhalten braucht, welche mit einer Hochsprache nicht darstellbar sind.
intrinsics
Plattformabhängig
ASM braucht man nur dann wenn es wieder mal neue CPU-Befehle gibt, welche der Compiler noch nicht kennt/anwenden kann.
Anwendungen mit DSP-Algorithmen würden ohne Assembler-Optimierungen ziemlich bescheiden laufen
Oder man Strukturen/Verhalten braucht, welche mit einer Hochsprache nicht darstellbar sind.
Methoden die so eine Abstraktheit verlangen, sollten auch nicht Teil einer Rechenzeit fordernden InnerLoop sein.
Der Programmierer, welcher besser optimiert als ein Compiler den gibt es nicht mehr.
Ein Compiler wurde auch nur von einem Menschen geschrieben oder meinst du Optimierungen zur Laufzeit?
Außerdem muss man den C-Code dem Compiler auch "schmackhaft" machen
Bsp?
16x16 BlockSummenDifferenz
(optimiertes) C
_uint32 sad16x16_c(_uint8 *src,_uint8 *ref,_uint32 bestsad,_uint32 ustride)
{
_uint8 const *psrc=src;
_uint8 const *pref=ref;
_uint32 sumabs = 0;
for (_uint32 y=0;y<16;y++)
{
sumabs += ABS(_sint32(psrc[0]) - (_sint32)pref[0]);
sumabs += ABS(_sint32(psrc[1]) - (_sint32)pref[1]);
sumabs += ABS(_sint32(psrc[2]) - (_sint32)pref[2]);
sumabs += ABS(_sint32(psrc[3]) - (_sint32)pref[3]);
sumabs += ABS(_sint32(psrc[4]) - (_sint32)pref[4]);
sumabs += ABS(_sint32(psrc[5]) - (_sint32)pref[5]);
sumabs += ABS(_sint32(psrc[6]) - (_sint32)pref[6]);
sumabs += ABS(_sint32(psrc[7]) - (_sint32)pref[7]);
sumabs += ABS(_sint32(psrc[8]) - (_sint32)pref[8]);
sumabs += ABS(_sint32(psrc[9]) - (_sint32)pref[9]);
sumabs += ABS(_sint32(psrc[10]) - (_sint32)pref[10]);
sumabs += ABS(_sint32(psrc[11]) - (_sint32)pref[11]);
sumabs += ABS(_sint32(psrc[12]) - (_sint32)pref[12]);
sumabs += ABS(_sint32(psrc[13]) - (_sint32)pref[13]);
sumabs += ABS(_sint32(psrc[14]) - (_sint32)pref[14]);
sumabs += ABS(_sint32(psrc[15]) - (_sint32)pref[15]);
if (sumabs >= bestsad) return sumabs;
psrc+=ustride;
pref+=ustride;
}
return sumabs;
}
MMX (Extended)
das dein Compiler (ohne SSE4.1 :tongue:) das besser kann als das, bezweifle ich
[GLOBAL _sad16x16_mmxext]
[SECTION .text]
ALIGN 16
sad_p_psrc equ 4+12
sad_p_pref equ 4+12+4
sad_p_bestsad equ 4+12+8
sad_p_stride equ 4+12+12
%macro SAD_2x16E 0
movq mm0,[eax]
movq mm1,[eax+8]
psadbw mm0,[ecx]
psadbw mm1,[ecx+8]
movq mm2,[eax+edx]
movq mm3,[eax+edx+8]
psadbw mm2,[ecx+edx]
psadbw mm3,[ecx+edx+8]
paddw mm4,mm0
paddw mm4,mm1
paddw mm4,mm2
paddw mm4,mm3
lea eax,[eax+2*edx]
lea ecx,[ecx+2*edx]
%endmacro
_sad16x16_mmxext:
push esi
push edi
push ebp
mov ebp,esp
mov eax,[ebp+sad_p_psrc]
mov ecx,[ebp+sad_p_pref]
mov edx,[ebp+sad_p_stride]
pxor mm4,mm4
SAD_2x16E
SAD_2x16E
SAD_2x16E
SAD_2x16E
SAD_2x16E
SAD_2x16E
SAD_2x16E
SAD_2x16E
movd eax,mm4
mov esp,ebp
pop ebp
pop edi
pop esi
ret
Plattformabhängig
Eigentlich unterstützen alle Compiler inzwischen die gleichen Intrinsics. Zumindest GCC, Intel und Microsoft können alle die gleichen.
Insofern würde ich das nicht mehr wirklich "plattformabhängig" nennen. Wenn man x86-Intrinsics verwendet dann benützt man doch eh keine anderen Compiler.
Insofern würde ich das nicht mehr wirklich "plattformabhängig" nennen. Wenn man x86-Intrinsics verwendet dann benützt man doch eh keine anderen Compiler.
mit Plattform meinte ich eig. auch andere als x86
Ach so und da ist Assembler natürlich portabel. Willst du mich verarschen?
Ach so und da ist Assembler natürlich portabel. Willst du mich verarschen?
natürlich müsste ich dann ne neue Assemblermethode schreiben,
NASM-Kompilate gibts für fast jede Plattform
der eigentliche Quellcode bleibt davon unbeeindruckt.
und das finde ich ziemlich schick :)
Und was hindert dich daran den Intrinsic-Code in Modulen auszulagern?
So ein Schwachsinnsargument.
vBulletin®, Copyright ©2000-2024, Jelsoft Enterprises Ltd.