PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : NASM assembler mit c programm


Gast
2008-07-04, 22:24:28
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

Gast
2008-07-04, 22:46:11
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.

Gast
2008-07-05, 01:00:18
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.

pest
2008-07-05, 10:07:43
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.

pest
2008-07-05, 14:17:16
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.

pest
2008-07-05, 16:19:09
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

Coda
2008-07-05, 16:51:28
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.

pest
2008-07-05, 16:53:11
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

Coda
2008-07-05, 17:13:06
Ach so und da ist Assembler natürlich portabel. Willst du mich verarschen?

pest
2008-07-05, 17:22:31
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 :)

Coda
2008-07-05, 18:12:14
Und was hindert dich daran den Intrinsic-Code in Modulen auszulagern?

So ein Schwachsinnsargument.