11.07.2015 Aufrufe

Assembler in C/C++ Programmen (Borland)

Assembler in C/C++ Programmen (Borland)

Assembler in C/C++ Programmen (Borland)

MEHR ANZEIGEN
WENIGER ANZEIGEN

Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.

YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.

HTI Burgdorf 3Informatik Übergangx86-<strong>Assembler</strong> mit Hochsprache CBeispiel 1: E<strong>in</strong>b<strong>in</strong>den von Masch<strong>in</strong>encode-Bytes mit _asm _emitBei Microsoft und Intel können e<strong>in</strong>zelne Bytes mit _asm _emit direkt im Code platziertwerden. Das nachfolgende Beispiel zeigt wie drei NOP-Befehle (Code 0x90) an der aktuellenStelle def<strong>in</strong>iert werden und wie die Umsetzung im Compiler erfolgt.Bild 1: Disassemblierte Darstellung des Programms mit _asm-Anweisungen nach Beispiel 1. Plattform:Visual <strong>C++</strong> V6.0 mit Intel <strong>C++</strong> Compiler V7.1._asm-AnweisungenDurch das reservierte Wort _asm kann e<strong>in</strong> <strong>Assembler</strong>codeblock direkt <strong>in</strong> den C/<strong>C++</strong>Quelltext e<strong>in</strong>gefügt werden. Innerhalb des <strong>Assembler</strong>blockes gelten auch hier dieSyntaxregeln des <strong>Assembler</strong>s, der zum Compiler gehört. E<strong>in</strong> Zugriff auf C-Symbole ist aufe<strong>in</strong>fache Weise möglich wie auch Funktionsaufrufe der C-Laufzeitbibliothek.Das reservierte Wort _asm aktiviert den Inl<strong>in</strong>e-<strong>Assembler</strong>. Es muss immer <strong>in</strong> Verb<strong>in</strong>dung mite<strong>in</strong>er e<strong>in</strong>zelnen <strong>Assembler</strong>-Anweisung oder e<strong>in</strong>em Block von <strong>Assembler</strong>anweisungen stehen._asm nopDie _asm-Anweisung ist selbstterm<strong>in</strong>ierend, d.h. sie benötigt ke<strong>in</strong> Semikolon. Deshalb könnenauch mehrere _asm-Anweisungen direkt aufe<strong>in</strong>ander folgen._asm nop _asm nop _asm nopE<strong>in</strong> Semikolon nach jeder Anweisung zu setzen ist aber ke<strong>in</strong> Fehler.20.2.2004, G. Krucker


HTI Burgdorf 4Informatik Übergangx86-<strong>Assembler</strong> mit Hochsprache CBeispiel 2: E<strong>in</strong>fache _asm-Anweisungen <strong>in</strong> C/<strong>C++</strong> Code.Das folgende Beispiel zeigt das E<strong>in</strong>br<strong>in</strong>gen dreier NOP-Befehle <strong>in</strong> den C/<strong>C++</strong> Quellcode:#<strong>in</strong>clude <strong>in</strong>t ma<strong>in</strong>(){ cout


HTI Burgdorf 5Informatik Übergangx86-<strong>Assembler</strong> mit Hochsprache CBeispiel 3: _asm Anweisungen <strong>in</strong> <strong>C++</strong> Code.Das folgende Beispiel zeigt die Berechnung der Fakultät e<strong>in</strong>er e<strong>in</strong>gelesenen Ganzzahl. DieRechnung erfolgt iterativ mit e<strong>in</strong>er e<strong>in</strong>fachen Schleife.// Beispiel zum E<strong>in</strong>betten von <strong>Assembler</strong>code <strong>in</strong> <strong>C++</strong> Programme// <strong>Borland</strong> <strong>C++</strong> Builder V5.0 , W<strong>in</strong>32 Console Application// G. Krucker, 2.1.2004#pragma hdrstop#<strong>in</strong>clude #<strong>in</strong>clude // Fuer kbhit()//---------------------------------------------------------------------------<strong>in</strong>t ma<strong>in</strong>(){ <strong>in</strong>t e<strong>in</strong>gabeWert;<strong>in</strong>t fakWert;cout > e<strong>in</strong>gabeWert;_asm{ mov eax,1 // 0! = Initialwertmov ecx,e<strong>in</strong>gabeWert // Zugriff auf <strong>C++</strong> Variablecmp ecx,2 // Trivialfall n < 2jl end$loop: imul ecx// n = n * (n-1)!dec ecx // n = n -1cmp ecx,2 // Ende wenn n < 2jnl $loopend:mov fakWert,eax // In <strong>C++</strong> Variable speichern}cout


HTI Burgdorf 6Informatik Übergangx86-<strong>Assembler</strong> mit Hochsprache CZugriff auf C/<strong>C++</strong> Runtime Library FunktionenIm <strong>in</strong>tegrierten <strong>Assembler</strong> können auch C/<strong>C++</strong> Funktionen der Runtime-Library verwendetwerden. Ebenso s<strong>in</strong>d auch Aufrufe der W<strong>in</strong>32-API möglich. Leider s<strong>in</strong>d die RTL-Funktionennicht sehr detailliert dokumentiert. Am besten benutzt man die Funktion zuerst e<strong>in</strong>mal <strong>in</strong> derHochsprache und schaut im disassemblierten Code nach wie die Funktion auf <strong>Assembler</strong>ebenegenau heisst und wie die Parametrisierung erfolgt. E<strong>in</strong> Zugriff auf <strong>in</strong>l<strong>in</strong>e-def<strong>in</strong>ierte -Funktionen ist aus nahe liegenden Gründen nicht möglich.Beispiel 4: C-Funktionsaufruf <strong>in</strong> _asm Anweisungen.Das folgende Beispiel zeigt den Zugriff auf C-Variablen und den Aufruf der pr<strong>in</strong>tf(..)-Funktion. Die Ausgabe erfolgt e<strong>in</strong>mal direkt <strong>in</strong> der Hochsprache und e<strong>in</strong> weiteres mal aufStufe <strong>Assembler</strong>:// Beispiel zum Aufruf von C-Libraryfunktionen und Zugriff auf C-Variablen aus dem// Inl<strong>in</strong>e-<strong>Assembler</strong>block.// <strong>Borland</strong> <strong>C++</strong> Builder V5.0 , W<strong>in</strong>32 Console Application// G. Krucker, 2.1.2004#pragma <strong>in</strong>l<strong>in</strong>e // Inl<strong>in</strong>e-<strong>Assembler</strong> ohne Meldung verwenden#<strong>in</strong>clude // Fuer kbhit()#<strong>in</strong>clude //---------------------------------------------------------------------------// Fuer die Operationen im _asm-Block gilt im Wesentlichen die// TASM-Sprachdef<strong>in</strong>ition.<strong>in</strong>t ma<strong>in</strong>(){ <strong>in</strong>t a=1,b=2;const char fmtStr[]="Werte nach _asm-Sequenz:\na=%d, b=%d\n";const char *f=fmtStr;asm{ mov eax, amov ebx, bmov b,eaxmov a,ebx// Zugriffe auf die C-Variablen – Werte vertauschen}};// Direkte Ausgabepr<strong>in</strong>tf("Werte nach _asm-Sequenz:\na=%d, b=%d\n",a,b);// Ausgabe <strong>in</strong> <strong>Assembler</strong> mit der _pr<strong>in</strong>tf-Library-Funktion_asm{ push bpush alea eax,fmtStrpush eaxcall _pr<strong>in</strong>tf // Aufruf der pr<strong>in</strong>t-Libraryfunktion aus CC3250.DLLadd esp,0ch // Stackbere<strong>in</strong>igung (Parameter wieder entfernen)}while (!kbhit());return 0;Bemerkung: Beim Aufruf der _pr<strong>in</strong>tf-RTL-Funktion im _asm-Block muss e<strong>in</strong> Zeiger aufden Formatstr<strong>in</strong>g fmtStr übergeben werden. Dies erfolgt hier mit LEA/PUSH. E<strong>in</strong> direktesPUSH OFFSET funktioniert (eigenartigerweise) nicht.Der gezeigte Code wird durch <strong>Borland</strong> <strong>C++</strong> Builder 5.0 umgesetzt:20.2.2004, G. Krucker


HTI Burgdorf 7Informatik Übergangx86-<strong>Assembler</strong> mit Hochsprache CBild 3: Disassemblierte Darstellung des Programms nach Beispiel 4 mit Aufruf e<strong>in</strong>er Funktion der C-Runtime Library. Plattform:Boland <strong>C++</strong> Builder 5.0.Bei der Verwendung von Inl<strong>in</strong>e-<strong>Assembler</strong> wird bei <strong>Borland</strong> automatisch e<strong>in</strong> *.asm-File erzeugt. Esenthält den vom Compiler erzeugten Zwischencode aus der Hochsprache für den <strong>Assembler</strong>. Dieses Filekann zur Lokalisierung von Fehlern <strong>in</strong> den _asm-Anweisungen nützlich se<strong>in</strong>..386pifdef ??versionif ??version GT 500H.mmxendifendifmodel flatifndef ??version?debug macroendmendif?debug S "\\Wendy\hta-be dok\EB01-1\Informatik 5 Uebergang\<strong>Assembler</strong>\<strong>Borland</strong> Inl<strong>in</strong>e <strong>Assembler</strong> I\Inl<strong>in</strong>e<strong>Assembler</strong>1Unit.c"?debug T "\\Wendy\hta-be dok\EB01-1\Informatik 5 Uebergang\<strong>Assembler</strong>\<strong>Borland</strong> Inl<strong>in</strong>e <strong>Assembler</strong> I\Inl<strong>in</strong>e<strong>Assembler</strong>1Unit.c"_TEXT segment dword public use32 'CODE'_TEXT ends_DATA segment dword public use32 'DATA'_DATA ends_BSS segment dword public use32 'BSS'_BSS ends$$BSYMS segment byte public use32 'DEBSYM'$$BSYMS ends$$BTYPESsegment byte public use32 'DEBTYP'$$BTYPESends$$BNAMESsegment byte public use32 'DEBNAM'$$BNAMESends$$BROWSEsegment byte public use32 'DEBSYM'$$BROWSEends$$BROWFILE segment byte public use32 'DEBSYM'$$BROWFILE endsDGROUP group _BSS,_DATA20.2.2004, G. Krucker


HTI Burgdorf 8Informatik Übergangx86-<strong>Assembler</strong> mit Hochsprache C_TEXT segment dword public use32 'CODE'__getch proc near?live1@0:?debug T "T:\BORLAND\CBUILDER5\INCLUDE\conio.h"?debug L 183push ebpmov ebp,esp@1:call _getch?debug L 183@3:@2:pop ebpret?debug L 0__getch endp_TEXT ends$$BSYMS segment byte public use32 'DEBSYM'db 2db 0db 0db 0dw 46dw 516dw 0dw 0dw 0dw 0dw 0dw 0dd ?patch1dd ?patch2dd ?patch3df __getchdw 0dw 4096dw 0dw 1dw 0dw 0dw 0?patch1 equ @3-__getch+2?patch2 equ 0?patch3 equ @3-__getchdw 2dw 6$$BSYMS ends_DATA segment dword public use32 'DATA'$imcmcaia label bytedb 87db 101db 114db 116db 101db 32db 110db 97db 99db 104db 32db 95db 97db 115db 109db 45db 83db 101db 113db 117db 101db 110db 122db 58db 10db 97db 61db 37db 100db 44db 32db 98db 61db 37db 100db 10db 0_DATA ends20.2.2004, G. Krucker


HTI Burgdorf 9Informatik Übergangx86-<strong>Assembler</strong> mit Hochsprache C_TEXT segment dword public use32 'CODE'_ma<strong>in</strong> proc near?live1@32:?debug T "\\Wendy\hta-be dok\EB01-1\Informatik 5 Uebergang\<strong>Assembler</strong>\<strong>Borland</strong> Inl<strong>in</strong>e <strong>Assembler</strong> I\Inl<strong>in</strong>e<strong>Assembler</strong>1Unit.c"?debug L 19push ebpmov ebp,espadd esp,-52push ebxpush esipush edi?debug L 20@4:mov dword ptr [ebp-4],1mov dword ptr [ebp-8],2?debug L 21mov esi,offset $imcmcaialea edi,dword ptr [ebp-48]mov ecx,9rep movsdmovsb?debug L 23lea eax,dword ptr [ebp-48]mov dword ptr [ebp-52],eax?debug L 24mov eax, dword ptr [ebp-4]?debug L 25mov ebx, dword ptr [ebp-8]?debug L 26mov dword ptr [ebp-8],eax?debug L 27mov dword ptr [ebp-4],ebx?debug L 32push dword ptr [ebp-8]push dword ptr [ebp-4]push offset s@call _pr<strong>in</strong>tfadd esp,12?debug L 35push dword ptr [ebp-8]?debug L 36push dword ptr [ebp-4]?debug L 37lea eax,byte ptr [ebp-48]?debug L 38push eax?debug L 39call _pr<strong>in</strong>tf?debug L 40add esp,0ch?debug L 42@5:@6:call _kbhittest eax,eaxje short @5?debug L 43xor eax,eax?debug L 44@8:@7:pop edipop esipop ebxmov esp,ebppop ebpret?debug L 0_ma<strong>in</strong> endp_TEXT ends$$BSYMS segment byte public use32 'DEBSYM'dw 52dw 517dw 0dw 0dw 0dw 0dw 0dw 0dd ?patch4dd ?patch5dd ?patch6df _ma<strong>in</strong>dw 0dw 4098dw 0dw 2dw 0dw 0dw 0db 5db 95db 109db 97db 105db 110dw 18dw 512dw 65484dw 65535dw 4100dw 0dw 3dw 0dw 0dw 0dw 18dw 512dw 65488dw 65535dw 4102dw 020.2.2004, G. Krucker


HTI Burgdorf 10Informatik Übergangx86-<strong>Assembler</strong> mit Hochsprache Cdw 4dw 0dw 0dw 0dw 18dw 512dw 65528dw 65535dw 116dw 0dw 5dw 0dw 0dw 0dw 18dw 512dw 65532dw 65535dw 116dw 0dw 6dw 0dw 0dw 0?patch4 equ @8-_ma<strong>in</strong>+7?patch5 equ 0?patch6 equ @8-_ma<strong>in</strong>dw 2dw 6dw 8dw 531dw 7dw 65472dw 65535$$BSYMS ends_DATA segment dword public use32 'DATA's@ label byte; s@+0:db "Werte nach _asm-Sequenz:",10; s@+25:db "a=%d, b=%d",10,0align 4_DATA ends_TEXT_TEXTsegment dword public use32 'CODE'endsextrn _getch:nearpublic _ma<strong>in</strong>extrn _pr<strong>in</strong>tf:nearextrn _kbhit:near$$BSYMS segment byte public use32 'DEBSYM'dw 16dw 4dw 117dw 0dw 0dw 7dw 0dw 0dw 0dw 16dw 4dw 116dw 0dw 0dw 8dw 0dw 0dw 0dw 16dw 4dw 33dw 0dw 0dw 9dw 0dw 0dw 0dw 16dw 4dw 33dw 0dw 0dw 10dw 0dw 0dw 0dw 16dw 4dw 33dw 0dw 0dw 11dw 0dw 0dw 0dw 16dw 4dw 18dw 0dw 0dw 12dw 0dw 0dw 0dw ?patch7dw 1db 3db 0db 0db 2420.2.2004, G. Krucker


HTI Burgdorf 11Informatik Übergangx86-<strong>Assembler</strong> mit Hochsprache Cdb 11db 66db 67db 67db 51db 50db 32db 53db 46db 53db 46db 49?patch7 equ 18$$BSYMS ends$$BTYPESsegment byte public use32 'DEBTYP'db 2,0,0,0,14,0,8,0,116,0,0,0,0,0,0,0db 1,16,0,0,4,0,1,2,0,0,14,0,8,0,116,0db 0,0,0,0,0,0,3,16,0,0,4,0,1,2,0,0db 8,0,2,0,10,0,5,16,0,0,8,0,1,0,1,0db 16,0,0,0,8,0,1,0,1,0,7,16,0,0,18,0db 3,0,16,0,0,0,17,0,0,0,0,0,0,0,37,0db 37,0,14,0,8,0,116,0,0,0,0,0,0,0,9,16db 0,0,4,0,1,2,0,0,14,0,8,0,116,0,0,0db 64,0,2,0,11,16,0,0,12,0,1,2,2,0,4,16db 0,0,0,0,0,0,14,0,8,0,116,0,0,0,0,0db 0,0,13,16,0,0,4,0,1,2,0,0$$BTYPESends$$BNAMESdbdbdbdbdbdbdbdbdbdbdbdb$$BNAMESsegment byte public use32 'DEBNAM'6,'_getch'4,'ma<strong>in</strong>'1,'f'6,'fmtStr'1,'b'1,'a'6,'size_t'9,'ptrdiff_t'7,'wchar_t'6,'w<strong>in</strong>t_t'8,'wctype_t'6,'fpos_t'ends?debug D "T:\BORLAND\CBUILDER5\INCLUDE\_nfile.h" 10307 8192?debug D "T:\BORLAND\CBUILDER5\INCLUDE\stdio.h" 10307 8192?debug D "T:\BORLAND\CBUILDER5\INCLUDE\_null.h" 10307 8192?debug D "T:\BORLAND\CBUILDER5\INCLUDE\_defs.h" 10307 8192?debug D "T:\BORLAND\CBUILDER5\INCLUDE\_stddef.h" 10307 8192?debug D "T:\BORLAND\CBUILDER5\INCLUDE\conio.h" 10307 8192?debug D "\\Wendy\hta-be dok\EB01-1\Informatik 5 Uebergang\<strong>Assembler</strong>\<strong>Borland</strong> Inl<strong>in</strong>e <strong>Assembler</strong> I\Inl<strong>in</strong>e<strong>Assembler</strong>1Unit.c" 12323 29287endBeispiel 5: Str<strong>in</strong>g-Funktionsaufruf <strong>in</strong> _asm Anweisung.Das folgende Beispiel zeigt die Benutzung e<strong>in</strong>er C-Str<strong>in</strong>gfunktion. Dazu muss im C/<strong>C++</strong> Teil e<strong>in</strong>#<strong>in</strong>clude erfolgen, auch wenn die Funktion erst auf <strong>Assembler</strong>ebene verwendet wird.Dies gilt auch für andere Funktionen der Runtime Library.//---------------------------------------------------------------------------#<strong>in</strong>clude #pragma <strong>in</strong>l<strong>in</strong>e// Inl<strong>in</strong>e <strong>Assembler</strong> ohne Meldung aktivieren#pragma hdrstop#<strong>in</strong>clude //---------------------------------------------------------------------------<strong>in</strong>t ma<strong>in</strong>(){ <strong>in</strong>t i;char str<strong>in</strong>g[]="Hallo";<strong>in</strong>t len;cout


HTI Burgdorf 13Informatik Übergangx86-<strong>Assembler</strong> mit Hochsprache CC-Hauptmodul:Im Hauptmodul wird der Funktionsprototyp def<strong>in</strong>iert. Normalerweise gilt für C-Compiler dieE<strong>in</strong>stellung cdecl als Standard, dann kann diese Angabe entfallen.Bild 4: Parameterübergabe nach C. Im Hochsprachenteil wird die externe Funktion über den Prototyp def<strong>in</strong>iert.In e<strong>in</strong>em <strong>C++</strong> Programm muss der Funktionsprototyp mit extern “C “def<strong>in</strong>iert werdendamit ke<strong>in</strong>e <strong>C++</strong> Typ<strong>in</strong>formation an den Funktionsnamen angehängt wird. Dies würde zue<strong>in</strong>em L<strong>in</strong>ker-Fehler führen.<strong>Assembler</strong>modul:Im <strong>Assembler</strong>modul wird die Funktion <strong>in</strong> proc … endp codiert. Der Funktionsname wirdmit public c exportiert, d.h. für die anderen Module sichtbar gemacht. Der H<strong>in</strong>weis c beiproc und public bewirkt, dass die Namen automatisch mit e<strong>in</strong>em Underscore (als _func)exportiert werden, weil der C-Compiler alle Namen mit e<strong>in</strong>em Underscore verwaltet. Fernerwerden c-exportierte Namen case-sensitive behandelt.Bild 5: <strong>Assembler</strong>modul zur Parameterübergabe nach C. Die Funktion wird mit proc c def<strong>in</strong>iert. Der Funktionsnamewird mit public c exportiert.Das Programm wird gestartet und bis zur ret-Anweisung im <strong>Assembler</strong>modul mit demDebugger ausgeführt. Wir sehen nachher wie die Parameter im Stack liegen (Fenster untenrechts).Ebenso sieht man im disassemblierten Code von ma<strong>in</strong>(), dass nach dem Funktionsaufrufcall func(<strong>in</strong>t signed char,<strong>in</strong>t) die Stackbere<strong>in</strong>igung mit add esp,0x0c erfolgt.20.2.2004, G. Krucker


HTI Burgdorf 15Informatik Übergangx86-<strong>Assembler</strong> mit Hochsprache C<strong>Assembler</strong>modul:Die Funktion wird hier als proc pascal def<strong>in</strong>iert. Ebenso die Publikation public pascalFUNC. Namen werden hier <strong>in</strong> Grossschrift geschrieben. Pascal-bezogene Symbole werden <strong>in</strong>den e<strong>in</strong>zelnen Modulen immer <strong>in</strong> Grosschrift importiert und exportiert.Bild 8: <strong>Assembler</strong>modul zur Parameterübergabe nach Pascal. Die Funktion wird mit proc pascal def<strong>in</strong>iert. DerFunktionsname wird mit public pascal exportiert.Das Programm wird gestartet und bis zur ret 0x0c-Anweisung im <strong>Assembler</strong>modul mit demDebugger ausgeführt. Wir sehen nachher wie die Parameter im Stack liegen (Fenster untenrechts).Bild 9: Programmbeispiel mit Parameterübergabe nach Pascal im Debugger. Plattform: <strong>Borland</strong> <strong>C++</strong> Builder 5.0Im disassemblierten Code von ma<strong>in</strong>() sieht man, dass nach dem Funktionsaufruf callfunc(<strong>in</strong>t signed char,<strong>in</strong>t) ke<strong>in</strong>e Stackbere<strong>in</strong>igung erfolgt. Diese wird <strong>in</strong> deraufgerufenen Funktion mit ret 0Ch erledigt. Die Angabe 0Ch besagt, dass beim Rücksprung0Ch=12=3 Parameter à 4Bytes vom Stack gelöscht werden.20.2.2004, G. Krucker


HTI Burgdorf 16Informatik Übergangx86-<strong>Assembler</strong> mit Hochsprache CAndere ParameterübergabetechnikenDie Übergabemethoden pascal und c s<strong>in</strong>d sicherlich die beiden wichtigsten Verfahren. AusGründen der Kompatibilität zu anderen Programmiersprachen existieren noch andere Verfahren.SYSCALL, STDCALL, BASIC, FORTRANAuch sie unterscheiden sich <strong>in</strong> der Art und Reihenfolge wie die Argumente übergeben werdenund wie die Stackbere<strong>in</strong>igung erfolgt. Detaillierte Informationen s<strong>in</strong>d <strong>in</strong> den produktespezifischenProgrammierhandbüchern zu f<strong>in</strong>den. [MASMPG-92],[BORASMBH-92],[BORASMRH-92].FunktionswertrückgabenFunktionswerte werden je nach Typ direkt über Prozessorregister oder über Zeiger auf e<strong>in</strong>eVariable übergeben.char al 8 Bitshort ax 16 Bitlong eax 32 BitZeiger eax 32 BitStruct Bis 4 Bytes: eax>4 Bytes über VariablenreferenzArray Zeiger <strong>in</strong> eax 32 BitIn 16-Bit Modulen werden 32-Bit Werte über DX:AX zurück gegeben, wobei DX dashöherwertige Wort ist.20.2.2004, G. Krucker


HTI Burgdorf 17Informatik Übergangx86-<strong>Assembler</strong> mit Hochsprache CBeispiel 6: Fakultätsberechnung mit externem <strong>Assembler</strong>modul und Funktionswertrückgabe.In e<strong>in</strong>em <strong>C++</strong> Programm soll mit e<strong>in</strong>em externen <strong>Assembler</strong>modul e<strong>in</strong>e Funktion fak zurVerfügung gestellt werden. Das Argument wird <strong>in</strong> C-Standardnotation über Parameterübergeben, das Resultat über Funktionswertrückgabe. Mit e<strong>in</strong>em Hauptprogramm wird dieAnwendung der Funktion gezeigt.Lösung:Da es sich um e<strong>in</strong> <strong>C++</strong> Programm handelt (File-Extension des aufrufenden Moduls ist *.cpp),muss der Funktionsprototyp als extern “C“ def<strong>in</strong>iert werden. Das <strong>Assembler</strong>modul wird mitder Funktionalität analog Beispiel 3 erstellt.Der Funktionsname wird über fak proc c…fak endp def<strong>in</strong>iert und mit public c fakexportiert:Bild 10: Parameterübergabe und Funktionswertrückgabe bei e<strong>in</strong>er extern “C“ def<strong>in</strong>ierten Funktion nach Beispiel 6.20.2.2004, G. Krucker


HTI Burgdorf 18Informatik Übergangx86-<strong>Assembler</strong> mit Hochsprache CBild 11: Debuggerfenster der CPU mit Darstellung des erzeugten Codes nach Beispiel 6. Aus Platzgründen wurden die Funktionen ma<strong>in</strong>und fak <strong>in</strong> separaten Fenstern dargestellt.20.2.2004, G. Krucker


HTI Burgdorf 19Informatik Übergangx86-<strong>Assembler</strong> mit Hochsprache CAlternative Lösung:Man kann die Direktive extern “C“ weglassen, wenn die <strong>C++</strong> Namenerweiterung für dieextern def<strong>in</strong>ierte Funktion bekannt ist. Die Namenerweiterung wurde notwendig, weil <strong>in</strong> <strong>C++</strong>Funktionen denselben Namen haben dürfen, sofern sie sich <strong>in</strong> den Parametern unterscheiden. DieUnterscheidung erfolgt <strong>in</strong> Typ und Anzahl.Für dieses Beispiel wäre der erweiterte Funktionsname @fak$qi. Die Funktion muss auf Stufe<strong>Assembler</strong> als syscall def<strong>in</strong>iert werden. syscall bewirkt, dass der Name casesensitivebehandelt wird, aber ohne Underscore exportiert wird. Die Stackbere<strong>in</strong>igung erfolgt beisyscall wie bei c durch den Aufrufer. (Vgl. auch [MSAMPG-92], S.309)Bild 12: Parameterübergabe und Funktionswertrückgabe bei e<strong>in</strong>er <strong>C++</strong> def<strong>in</strong>ierten Funktion nach Beispiel 6. DerFunktionsname <strong>in</strong> <strong>Assembler</strong> trägt die Namenerweiterung @..$qi.20.2.2004, G. Krucker


HTI Burgdorf 20Informatik Übergangx86-<strong>Assembler</strong> mit Hochsprache CBild 13: Debuggerfenster der CPU mit Darstellung des erzeugten Codes für die alternative Lösung nach Beispiel 6. Aus Platzgründenwurden die Funktionen ma<strong>in</strong> und fak <strong>in</strong> separaten Fenstern dargestellt.20.2.2004, G. Krucker

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!