first commit
This commit is contained in:
commit
0a36a1ef0e
|
@ -0,0 +1,32 @@
|
|||
; ADDIT: ASM-Beispiel zur Addition mit dem SBC86
|
||||
; C.Koch | 03.11.2010
|
||||
|
||||
org 100h
|
||||
cpu 8086
|
||||
|
||||
START: mov ax,1
|
||||
mov dx,1 ; Summand 1: dx:ax = 00010001h
|
||||
mov bx,nVal32 ; Summand 2: Speicher
|
||||
|
||||
call AddNow
|
||||
|
||||
mov word [nResult],ax ; Ergebnis im Speicher ablegen
|
||||
mov word [nResult+2],dx
|
||||
|
||||
jmp START
|
||||
|
||||
AddNow:
|
||||
add ax, word [bx]
|
||||
adc dx, word [bx+2] ; Addiere mit CF!
|
||||
; alternative Speicheradressierung:
|
||||
; add bx,2 ; Zeiger verstellen
|
||||
; adc dx, word [bx] ; Addiere mit CF! - fkt. das?
|
||||
|
||||
ret ; Unterfunktion verlassen
|
||||
|
||||
nVal32 dd 0012ABCDh ; Adresse? Wert=
|
||||
nResult dd 0 ; Adresse? Wert=
|
||||
|
||||
sText db 'Hier koennte Ihre Werbung stehen'
|
||||
|
||||
|
Binary file not shown.
|
@ -0,0 +1,30 @@
|
|||
; ADDIT: ASM-Beispiel zur Division mit dem SBC86
|
||||
; C.Koch | 03.11.2010
|
||||
|
||||
org 100h
|
||||
cpu 8086
|
||||
|
||||
START:
|
||||
; **** Byte-Division ****
|
||||
mov ax,4522 ; Dividend ist immer das AX-Register (16 Bit)
|
||||
mov bh,120 ; Divisor sei ein Wert in BH (8 Bit)
|
||||
div bh ; AX/BH = Quotient in AL, Ganzzahlrest in AH
|
||||
|
||||
mov byte [nErgebnis],al ; Quotient -> Speicher
|
||||
mov byte [nRest],ah ; Ganzzahlrest -> Speicher
|
||||
|
||||
; **** Wort-Division ****
|
||||
mov dx, 0 ; Dividend ist immer das RegisterPAAR DX:AX (32 Bit)
|
||||
mov ax,45220 ; Dividend, Bit 0...15
|
||||
mov bx,120 ; Divisor sei ein Wert in BX (16 Bit)
|
||||
div bx ; (DX:AX)/BX = Quotient in AX, Rest in DX
|
||||
|
||||
mov word [nErgebnis],ax ; Quotient -> Speicher
|
||||
mov word [nRest],dx ; Ganzzahlrest -> Speicher
|
||||
|
||||
jmp START
|
||||
|
||||
nErgebnis dw 0 ; Adresse? Wert=
|
||||
nRest dw 0 ; Adresse? Wert=
|
||||
|
||||
sText db 'Hier koennte Ihre Werbung stehen'
|
Binary file not shown.
|
@ -0,0 +1,11 @@
|
|||
; SWITCH: ASM-Beispiel zur Benutzung der Ports des SBC86
|
||||
; C.Koch | 28.10.2010
|
||||
|
||||
org 100h
|
||||
cpu 8086
|
||||
|
||||
SWITCH: in al,00h ; Schalter abfragen
|
||||
out 00h, al ; LEDs ansteuern
|
||||
|
||||
jmp SWITCH ; Endlosschleife
|
||||
|
Binary file not shown.
|
@ -0,0 +1,26 @@
|
|||
# Makefile zum Verlinken eines ASM-Moduls mit einem C-Programm
|
||||
# HS Emden/Leer | C.Koch
|
||||
# 11.06.2012 initial version
|
||||
# 11.12.2014 update 64-bit. Ubuntu 14.04 -> to compile 32-bit code on 64-bit environment:
|
||||
# $ sudo apt-get install gcc-multilib
|
||||
|
||||
# C-Quellcode kompilieren und mit ASM-Modul linken
|
||||
callecho: echo.o callecho.o
|
||||
gcc -m32 -o callecho callecho.o echo.o # linken
|
||||
|
||||
callecho.o: callecho.c
|
||||
gcc -m32 -c -o callecho.o callecho.c # compilieren
|
||||
|
||||
# ASM-Modul assemblieren
|
||||
echo.o: echo.asm
|
||||
nasm -f elf -o echo.o echo.asm
|
||||
|
||||
# Projekt aufraemen
|
||||
clean:
|
||||
@echo 'Ausgabedateien loeschen'
|
||||
rm -f callecho *.o *~
|
||||
|
||||
|
||||
|
||||
|
||||
|
Binary file not shown.
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
callecho.c
|
||||
Demo: C und Assembler verlinken
|
||||
HS Emden/Leer | C.Koch
|
||||
07.06.2013 initial version
|
||||
11.12.2014 minor changes
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
extern int _echo(int);
|
||||
short a;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
short *p;
|
||||
|
||||
printf(" -- C+Assembler: Echo --\n");
|
||||
a = 0x10;
|
||||
|
||||
printf("Rueckgabe: 0x%04x\n", _echo(a) );
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
/* Ausgabe der Symbole der Objekt-Module:
|
||||
cko@geo:echo$readelf -s echo.o
|
||||
cko@geo:echo$readelf -s callecho.o
|
||||
cko@geo:echo$readelf -s callecho
|
||||
*/
|
Binary file not shown.
|
@ -0,0 +1,36 @@
|
|||
; echo.asm
|
||||
; Demo: C und Assembler verlinken
|
||||
; HS Emden/Leer | C.Koch
|
||||
; 31.05.2013 initial version
|
||||
; 11.12.2014 local variables added
|
||||
|
||||
; **** Code-Segment ****
|
||||
section .text
|
||||
|
||||
global _echo
|
||||
|
||||
_echo:
|
||||
push ebp ; neuer Stackframe: BasePointer retten
|
||||
mov ebp,esp ; Stackpointer zum neuen BasePointer machen
|
||||
|
||||
sub esp, 4 ; ?
|
||||
mov [ebp-4], word 1
|
||||
|
||||
mov eax,0 ; Rueckgabewert zur C-Funktion: EAX-Register
|
||||
add ax, word [foo] ; ?
|
||||
add ax, word [ebp+8] ; Parameter holen
|
||||
add ax, word [ebp-4] ; ?
|
||||
|
||||
mov esp, ebp ; ?
|
||||
pop ebp ; BP wiederherstellen
|
||||
ret ; um die Uebergabeparameter kuemmert sich
|
||||
; das rufende Programm (add esp, 16)
|
||||
|
||||
; **** Daten-Segment ****
|
||||
section .data
|
||||
|
||||
; GLOBALE Variable anlegen und initialisieren.
|
||||
; C-Beispiel: short foo = 0;
|
||||
foo dw 2
|
||||
|
||||
|
Binary file not shown.
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
clspwap.c: TecPro Beispielprogramm
|
||||
Kurzbeschreibung: Sortieren der Kommandozeile
|
||||
Version mit Vektorelementen
|
||||
D. Ertelt, gccC.Koch | HS-Emden-Leer | 18.12.2010
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(int argc, char *argv[]) { /* **argv */
|
||||
|
||||
int i, j; /* Schleifenzaehler*/
|
||||
char *tmp;
|
||||
|
||||
/* Ist String i mit j identisch? Nein? Dann vertauschen. */
|
||||
for(i=1; i<argc ; i++)
|
||||
for(j=i+1; j<argc ; j++)
|
||||
/* strcmp: Rückgabe NULL -> Strings sind identisch
|
||||
Rückgabe > 0 -> das erste nicht identische Zeichen des String hat einen größeren Wert */
|
||||
if(strcmp(argv[i],argv[j]) > 0)
|
||||
{ tmp=argv[j]; argv[j]=argv[i]; argv[i]=tmp; }
|
||||
|
||||
/* Ausgabe der Parameter - alphabetisch sortiert */
|
||||
for(i=1; i<argc ; i++)
|
||||
printf("%s ", argv[i]);
|
||||
|
||||
printf("\n");
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
tp-enum.c: TecPro Beispielprogramm
|
||||
Kurzbeschreibung: eigene Datentypen als Aufzählung mit typedef
|
||||
C.Koch | HS-Emden-Leer | 25.11.2010
|
||||
|
||||
HINWEIS: Wenn eine Variable mit enum definiert wird, behandelt sie
|
||||
der Compiler als Integerzahl. Sie kann dann jeden Wert annehmen,
|
||||
nicht nur die in enum festgelegten.
|
||||
*/
|
||||
|
||||
#include <stdio.h> // diverse Standard-Input-Output-Funktionen
|
||||
|
||||
// neuen Datentyp deklarieren und definieren
|
||||
typedef enum { ROT=1, ROTGELB, GRUEN, GELB } eAmpelzustand;
|
||||
|
||||
|
||||
main()
|
||||
{
|
||||
eAmpelzustand ampel; // Variable deklarieren
|
||||
|
||||
printf("\nHallo Ostfriesland!\n"); // Ausgabe einer Zeichenkette
|
||||
ampel = ROT;
|
||||
printf("Status: %u\n", ampel);
|
||||
|
||||
ampel = ROTGELB;
|
||||
printf("Status: %u\n", ampel);
|
||||
|
||||
ampel = GRUEN;
|
||||
printf("Status: %u\n", ampel);
|
||||
|
||||
//ampel = SCHWARZ;
|
||||
//printf("Status: %u\n", ampel);
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
tp-enum.c: TecPro Beispielprogramm
|
||||
Kurzbeschreibung: eigene Datentypen als Aufzählung - Ampelsteuerung
|
||||
C.Koch | HS-Emden-Leer | 25.11.2010
|
||||
|
||||
HINWEIS: Wenn eine Variable mit enum definiert wird, behandelt sie
|
||||
der Compiler als Integerzahl. Sie kann dann jeden Wert annehmen,
|
||||
nicht nur die in enum festgelegten.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h> // diverse Standard-Input-Output-Funktionen
|
||||
|
||||
// neuen Datentyp definieren
|
||||
enum eAmpelsteuerung { ROT=1, ROTGELB, GRUEN, GELB };
|
||||
|
||||
main()
|
||||
{
|
||||
//eAmpelzustand ampel; // Variable deklarieren
|
||||
enum eAmpelsteuerung ampel;
|
||||
|
||||
printf("\nHallo Ostfriesland!\n"); // Ausgabe einer Zeichenkette
|
||||
ampel = ROT;
|
||||
printf("Status: %u\n", ampel);
|
||||
|
||||
ampel = ROTGELB;
|
||||
printf("Status: %u\n", ampel);
|
||||
|
||||
ampel = GRUEN;
|
||||
printf("Status: %u\n", ampel);
|
||||
|
||||
//ampel = SCHWARZ;
|
||||
//printf("Status: %u\n", ampel);
|
||||
|
||||
printf("Modulo %u von %u ergibt %u.\n",20,3,20%3);
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
tp-file.c: TecPro Beispielprogramm
|
||||
Kurzbeschreibung: Die Standard C-Bibliothek
|
||||
C.Koch | HS-Emden-Leer | 06.04.2011
|
||||
|
||||
Compile: gcc -g -Wall -o tp-file tp-file.c
|
||||
Analyse: ddd tp-file
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
void FileWrite(char* sInput);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
char sInput[100];
|
||||
int iTest= 64;
|
||||
|
||||
printf("\n ---- Die Standard C-Bibliothek stdio ----\n");
|
||||
printf("iTest: \t %d %p %x %c\n",iTest, &iTest, iTest, iTest);
|
||||
|
||||
printf("-> Eingabe: ");
|
||||
gets(sInput);
|
||||
puts(sInput);
|
||||
|
||||
/* einfache String-Analyse zum bedingten Sprung via strcmp */
|
||||
if(strcmp(sInput,"exit"))
|
||||
FileWrite(sInput);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Demo-Funktion zur Verwendung von Dateien */
|
||||
void FileWrite(char* sInput)
|
||||
{
|
||||
FILE* fpDatei; /* "Handle" zur Adressierung von Dateien: File-Pointer */
|
||||
int iLoop;
|
||||
|
||||
puts("-> Schreibe Eingabe in Datei 'out.txt' ");
|
||||
/* Datei öffnen und via fprintf beschreiben*/
|
||||
fpDatei = fopen("out.txt","w");
|
||||
|
||||
fprintf(fpDatei," ---- Demo-Datei ----\n Die Eingabe lautete: *%s*\n",sInput);
|
||||
|
||||
for(iLoop=0x20; iLoop<=0x40; iLoop++)
|
||||
fprintf(fpDatei," iLoop: \t %03d %03x %c\n",iLoop, iLoop, (char) iLoop);
|
||||
|
||||
/* nach Bearbeitung die Datei wieder schließen */
|
||||
fclose(fpDatei);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
tp-heap.c: TecPro Beispielprogramm
|
||||
Kurzbeschreibung: Zeichenketten in C und dynamische Speicherverwaltung
|
||||
C.Koch | HS-Emden-Leer | 12.04.2011
|
||||
|
||||
Compile: gcc -g -Wall -o tp-heap tp-heap.c
|
||||
Analyse: ddd tp-heap
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h> /* z.B. dynamische Speicherverwaltung via calloc() */
|
||||
|
||||
#define DYNMEM 32*1024*1024 /* Größe des dynamischen Speicherbereichs definieren */
|
||||
|
||||
void FileWrite(char* sInput);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* Speicher auf dem Stack ist schnell adressiert,
|
||||
jedoch pro Applikation nur begrenzt verfügbar (siehe $ ulimit -a) */
|
||||
|
||||
/* Beispiel: Textdatei einlesen */
|
||||
/* Dateigröße? 8 kByte / 8MByte / 80 MByte? */
|
||||
char cTextA[8*1024]; /* STACK */
|
||||
char *cTextB;
|
||||
|
||||
FILE* fpDatei;
|
||||
char *cStatus;
|
||||
int iSize;
|
||||
|
||||
cTextB = calloc(DYNMEM,sizeof(char)); /* HEAP */
|
||||
|
||||
/* Programm abbrechen, falls ein Fehler
|
||||
bei der Speicherallozierung auftritt*/
|
||||
if(cTextB == NULL)
|
||||
{
|
||||
printf("-> FEHLER: Speicherallozierung nicht erfolgreich!\n");
|
||||
return -1;
|
||||
}
|
||||
printf("\nDynamischer Speicher: %d kByte @ %p - %p\n", (DYNMEM * sizeof(char))/1024, cTextB, cTextB+(DYNMEM * sizeof(char)) );
|
||||
|
||||
/* Datei öffnen und zeilenweise auslesen */
|
||||
fpDatei = fopen("tp-file/out.txt","r");
|
||||
do
|
||||
{
|
||||
cStatus = fgets(cTextA, 100, fpDatei);
|
||||
/* Länge des gelesenen Strings ermitteln */
|
||||
iSize = strlen(cTextA);
|
||||
cTextA[iSize-1]='*';
|
||||
sprintf(cTextB,"%03u Zeichen -> %s |",iSize, cTextA);
|
||||
puts(cTextB);
|
||||
getchar();
|
||||
}while(cStatus != NULL);
|
||||
|
||||
/* Datei wieder schließen und Speicher freigeben*/
|
||||
fclose(fpDatei);
|
||||
free(cTextB);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
tp-local.c: TecPro Beispielprogramm
|
||||
Kurzbeschreibung: lokale Datenobjekte / Gültigkeit
|
||||
C.Koch | HS-Emden-Leer | 25.11.2010
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void main(void)
|
||||
{
|
||||
int myObj;
|
||||
int* myObjPtr;
|
||||
|
||||
myObj = 20;
|
||||
myObjPtr = &myObj;
|
||||
|
||||
/* Zugriff auf beliebige Adressen - was passiert?*/
|
||||
/* myObjPtr = (int*) 0x55555; */
|
||||
|
||||
*myObjPtr = 10;
|
||||
|
||||
printf("->> Wert myObj \t: %i", myObj);
|
||||
|
||||
int a = 5;
|
||||
|
||||
{
|
||||
int a = 20;
|
||||
|
||||
a++;
|
||||
}
|
||||
|
||||
/* Welcher Wert wird ausgegeben - 5 oder 20 oder ... ?*/
|
||||
printf("\n->> Wert a \t: %d\n",a);
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
tp-printf.c: Beispielprogramm HnP
|
||||
Kurzbeschreibung: stdlib C, printf() und Bitmanipulation
|
||||
C.Koch | HS-Emden-Leer
|
||||
19.04.2013 Initialversion
|
||||
07.11.2014 Erweiterung mit Datentypgröße und 32/64-Bit
|
||||
|
||||
Compile: gcc -o tp-printf tp-printf.c 64-Bit
|
||||
gcc -m32 -o tp-printf tp-printf.c 32-Bit
|
||||
Exec info: objdump -f tp-printf
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int i = -1;
|
||||
char string[] = "+++ Hallo Ostfriesland +++";
|
||||
char *p = string;
|
||||
|
||||
printf("1: %s \n",p);
|
||||
printf("2: %u \n",i);
|
||||
printf("3: %c \n",i);
|
||||
printf("4: 0x%x \n\n",i);
|
||||
|
||||
printf("5: 0x%lx \n", (unsigned long) (&i));
|
||||
printf("6: 0x%lx \n", (unsigned long) (&main));
|
||||
printf("7: 0x%x \n",(unsigned int) ((unsigned long) (&i) & 0xffff));
|
||||
|
||||
printf("\n sizeof i: %i | p: %i\n", (int) sizeof(i), (int) sizeof(p));
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Beispielausgabe (32-Bit):
|
||||
linfan@camaro:~/.../beispieleC$ ./tp-printf
|
||||
1: +++ Hallo Ostfriesland +++
|
||||
2: 4294967295
|
||||
3: <EFBFBD>
|
||||
4: 0xffffffff
|
||||
|
||||
5: 0xffbcc808
|
||||
6: 0x804846d
|
||||
7: 0xc808
|
||||
|
||||
sizeof i: 4 | p: 4
|
||||
|
||||
|
||||
*/
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
tp-pvec.c: TecPro Beispielprogramm
|
||||
Kurzbeschreibung: Zeiger und Vektoren
|
||||
D.Ertelt, C.Koch | HS-Emden-Leer | 25.11.2010
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int main(void) {
|
||||
unsigned int a[6], i, *aPtr;
|
||||
|
||||
printf("Vorher: aPtr = 0x%08x &a = 0x%08x\n", aPtr, &a);
|
||||
for(i=0; i < 6; i++)
|
||||
printf("a[%d] = %d\n", i, a[i]);
|
||||
|
||||
printf("Nachher: aPtr = 0x%08x\n", (aPtr = a));
|
||||
for( ; aPtr < a + 6 ; aPtr++) {
|
||||
*aPtr = i--;
|
||||
printf("*(0x%08x) = %d\n", (aPtr), *aPtr); }
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
tp-regval.c: TecPro Beispielprogramm
|
||||
Kurzbeschreibung: Beispiel zum Adressoperator
|
||||
C.Koch | HS-Emden-Leer | 19.12.2010
|
||||
*/
|
||||
|
||||
|
||||
/* Frage: Welche Funktion hat das Typattribut "register" ?
|
||||
Wie wirkt es sich auf die Adressierung von Vaiablen aus? */
|
||||
register int nTestVal;
|
||||
int* pnZeiger;
|
||||
|
||||
void* pvZeiger; /* Frage: Was ist ein VOID-Pointer? Wie benutze ich ihn? */
|
||||
|
||||
void main(void)
|
||||
{
|
||||
nTestVal = 0xF0;
|
||||
pnZeiger = &nTestVal;
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
tp-sizeof.c: TecPro Beispielprogramm
|
||||
Kurzbeschreibung: Beispiel zur Strukturgroesse einzelner Datentypen
|
||||
C.Koch | HS-Emden-Leer | 19.12.2010
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* globale Datenobjekte deklarieren */
|
||||
int cText[20];
|
||||
int *pText;
|
||||
|
||||
typedef enum {NOKIA, SAMSUNG, LG, MOTOROLA, APPLE} eHandy;
|
||||
|
||||
typedef struct {eHandy Type; int Anzahl; char cLand[20];} stHersteller;
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
|
||||
/* lokale Datenobjekte deklarieren */
|
||||
stHersteller neuerHersteller;
|
||||
unsigned char ucBytes;
|
||||
|
||||
pText = cText;
|
||||
|
||||
/* groessen berechnen */
|
||||
ucBytes = sizeof(char);
|
||||
printf("Anzahl Bytes: %u \n", ucBytes);
|
||||
ucBytes = sizeof(pText);
|
||||
printf("Anzahl Bytes: %u \n", ucBytes);
|
||||
ucBytes = sizeof(eHandy);
|
||||
printf("Anzahl Bytes: %u \n", ucBytes);
|
||||
ucBytes = sizeof(neuerHersteller);
|
||||
printf("Anzahl Bytes: %u \n", ucBytes);
|
||||
|
||||
/* Rueckgabewert an das Betriebssystem */
|
||||
return (0);
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
tp-swap.c: TecPro Beispielprogramm
|
||||
Kurzbeschreibung: "call by reference / call by value"
|
||||
C.Koch | HS-Emden-Leer | 19.12.2010
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int swapRef(int* a, int* b);
|
||||
int swapVal(int a, int b);
|
||||
int swapMem(int* a, int* b);
|
||||
|
||||
void main(void)
|
||||
{
|
||||
/* auto -> Stack | static -> Datensegment*/
|
||||
static int a,b;
|
||||
|
||||
a = 10; b = 20;
|
||||
|
||||
swapVal(a,b);
|
||||
printf("Var \t a =%i \t b= %i \n",a, b);
|
||||
swapRef(&a, &b);
|
||||
printf("Var \t a =%i \t b= %i \n",a, b);
|
||||
swapMem(&a, &b);
|
||||
printf("Var \t a =%i \t b= %i \n",a, b);
|
||||
}
|
||||
|
||||
int swapRef(int* a, int* b)
|
||||
{
|
||||
int temp;
|
||||
|
||||
temp = *a;
|
||||
*a = *b; *b = temp;
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
int swapVal(int a, int b)
|
||||
{
|
||||
int temp;
|
||||
|
||||
temp = a;
|
||||
a = b; b = temp;
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
/* Aufgabe: Wie muss die folgende Funktion geändert werden,
|
||||
falls die Variablen a und b auf dem Stack liegen und nicht im Datensegment? */
|
||||
int swapMem(int* a, int* b)
|
||||
{
|
||||
int temp;
|
||||
|
||||
temp = *a;
|
||||
*a = *(a+1); *(a+1) = temp;
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
org 100h
|
||||
cpu 8086
|
||||
|
||||
jmp START
|
||||
|
||||
BYTE1 db 32
|
||||
db 'Hardwarenahes Programmieren'
|
||||
times 4 db 0,'1'
|
||||
dw 1,2,3,4,1234
|
||||
dd 1234h
|
||||
|
||||
START: mov bx, BYTE1
|
||||
WDH: mov al, [bx]
|
||||
out 0, al
|
||||
inc bx
|
||||
jmp WDH
|
||||
|
|
@ -0,0 +1,186 @@
|
|||
org 100h
|
||||
cpu 8086
|
||||
|
||||
jmp start
|
||||
|
||||
; Variablen
|
||||
sollwert db tmin
|
||||
tcounts db 0 ; Impulszaehler fuer Servo, Vorwaertszaehler
|
||||
|
||||
anzeige times 3 db 0 ; Puffer fuer Ausgabe
|
||||
strlen equ $ - anzeige ; Laenge Zeichenpuffer
|
||||
|
||||
; Konstanten
|
||||
intab0 equ 20h ; Adresse Interrupttabelle PIT, Kanal 1
|
||||
eoi equ 20h ; End Of Interrupt (EOI)
|
||||
clrscr equ 0 ; Clear Screen
|
||||
getkey equ 1 ; Funktion auf Tastatureingabe warten
|
||||
ascii equ 1 ; Funktion ASCII-Zeichenausgabe
|
||||
hexbyte equ 4 ; HEX-Byte Ausgabe
|
||||
conin equ 5 ; Console IN
|
||||
conout equ 6 ; Console OUT
|
||||
pitc equ 0a6h ; Steuerkanal PIT
|
||||
pit1 equ 0a2h ; Counter 1 PIT
|
||||
pit2 equ 0a4h ; Counter 2 PIT
|
||||
ppi_ctl equ 0b6h ; Steuerkanal PPI (Parallelinterface)
|
||||
ppi_a equ 0b0h ; Kanal A PPI
|
||||
ppi_pa0 equ 1 ; LED 0
|
||||
ppi_pa1 equ 2 ; LED 1
|
||||
ppi_pa2 equ 4 ; LED 2
|
||||
ppi_pa3 equ 8 ; Lautsprecher
|
||||
ppi_pa6 equ 1 << 6 ; Servomotor
|
||||
ppi_b equ 0b2h ; Kanal B PPI
|
||||
ppi_c equ 0b4h ; Kanal C PPI
|
||||
ocw_2_3 equ 0c0h ; PIC (Interruptcontroller), OCW2,3
|
||||
ocw_1 equ 0c2h ; PIC (Interruptcontroller), OCW1
|
||||
icw_1 equ 0c0h ; PIC (Interruptcontroller), ICW1
|
||||
icw_2_4 equ 0c2h ; PIC (Interruptcontroller), ICW2,4
|
||||
leds equ 0 ; LED Port
|
||||
schalter equ 0 ; Schalterport
|
||||
keybd equ 80h ; SBC-86 Tastatur
|
||||
gokey equ 11h ; Taste "GO"
|
||||
outkey equ 15h ; Taste "OUT"
|
||||
sseg7 equ 9eh ; Segmentanzeige 7
|
||||
tcpwm equ 184 ; 1843200 Hz / 184 = ca. 10000 Hz = 0.1 ms
|
||||
; Taktzyklus
|
||||
; Zeitkonstante fuer PWM-Interrupt
|
||||
tpwm equ 200 ; Periodendauer des PWM-Signals (* 0.1 ms)
|
||||
tmax equ 25 ; Impulsdauer fuer 0 Grad (* 0.1 ms)
|
||||
tmin equ 6 ; Impulsdauer fuer 180 Grad (* 0.1 ms)
|
||||
divider equ 13 ; Vorteiler Wandlerwert
|
||||
; 0..255 -> 0..19 -> + tmin -> tmin..tmax
|
||||
ad_start1 equ 00110000b ; AD-Wandler starten und auf "read"
|
||||
ad_start2 equ 00100111b ; AD-Wandler nur "read" und LED's an
|
||||
|
||||
start:
|
||||
|
||||
; Initialisierung
|
||||
|
||||
mov ah, clrscr ; Anzeige aus
|
||||
int conout
|
||||
|
||||
call init ; Controller und Interruptsystem scharfmachen
|
||||
|
||||
mov al, 0
|
||||
out leds, al
|
||||
mov al, ad_start1 ; ADU init.
|
||||
out ppi_a, al
|
||||
mov al, ad_start2
|
||||
out ppi_a, al
|
||||
|
||||
; Hintergrundprogramm: Lesen des Wandlerwertes, Verarbeitung und Displayausgabe
|
||||
|
||||
again:
|
||||
in al, ppi_b ; Wandlerwert
|
||||
; ...
|
||||
; ...
|
||||
; ...
|
||||
jmp again
|
||||
|
||||
; Ausgabe einer ASCII-Zeichenkette
|
||||
|
||||
strout:
|
||||
; ...
|
||||
; ...
|
||||
; ...
|
||||
ret
|
||||
|
||||
; 8-Bit Division AL / BL
|
||||
; Return: Quotient in AL, Rest in AH
|
||||
; Zerstoert AX, BH
|
||||
; Algorithmus siehe:
|
||||
; https://www-user.tu-chemnitz.de/~heha/Mikrocontroller/Division.htm
|
||||
; Wuerde auch mit dem DIV-Befehl der CPU funktionieren, wieso dann das hier?
|
||||
|
||||
divide: xor ah, ah ; High-Teil Dividend
|
||||
mov bh, 8 ; Anzahl Bits Quotient
|
||||
_div: shl ax, 1 ; Dividend * 2
|
||||
cmp ah, bl ; teilbar?
|
||||
jb _smaller ; nein
|
||||
sub ah, bl ; ja, abziehen
|
||||
inc al ; Dividend, Bit 0 = 1
|
||||
_smaller:
|
||||
dec bh ; fertig?
|
||||
jnz _div ; nein, naechste Stelle
|
||||
ret
|
||||
|
||||
; Hornerschema rueckwaerts (Teilen des Wertes durch die Zielbasis bis nix mehr
|
||||
; da ist; die Reste der Division sind die Ziffern, von "hinten" (LOW) beginnend)
|
||||
; Hexwert (in AL) nach dezimal (ASCII-String) wandeln und in "anzeige" speichern
|
||||
; Zerstoert AX, BX, CX, DI
|
||||
|
||||
val2astr:
|
||||
mov di, anzeige + strlen - 1 ; Zielpuffer rueckwaerts beschreiben
|
||||
mov bl, 10 ; Dezimalwandlung (Zielbasis)
|
||||
xor cx, cx
|
||||
v1: call divide ; AL / BL, Rest in AH
|
||||
add ah, '0' ; --> ASCII
|
||||
mov [di], ah ; Zeichen in Puffer
|
||||
dec di ; vorherige Pufferstelle
|
||||
inc cl ; Zaehler++
|
||||
or al, al ; fertig? (Dividend zerdividiert?)
|
||||
jnz v1 ; noe, nochmal
|
||||
mov al, cl ; Anzahl
|
||||
mov cl, strlen ; max. Stringlaenge
|
||||
sub cl, al ; Anzahl Reststellen
|
||||
; out leds, al ; Kontrollausgabe
|
||||
jcxz v3 ; fertig?
|
||||
v2: mov byte [di], ' ' ; Rest loeschen
|
||||
dec di
|
||||
loop v2 ; fertig?
|
||||
v3: ret
|
||||
|
||||
; Initialisierung Controller und Interruptsystem
|
||||
|
||||
init:
|
||||
cli ; Interrupts aus
|
||||
|
||||
; PIT-Init.
|
||||
mov al, 01110110b ; Kanal 1, Mode 3, 16-Bit ZK
|
||||
out pitc, al ; Steuerkanal
|
||||
mov al, tcpwm & 0ffh ; Low-Teil Zeitkonstante
|
||||
out pit1, al
|
||||
mov al, tcpwm >> 8 ; High-Teil Zeitkonstante
|
||||
out pit1, al
|
||||
|
||||
; PPI-Init.
|
||||
mov al, 10001011b ; PPI A/B/C Mode 0, A Output, sonst Input
|
||||
out ppi_ctl, al
|
||||
jmp short $+2 ; I/O-Delay
|
||||
mov al, 0 ; LED's aus (high aktiv)
|
||||
out ppi_a, al
|
||||
|
||||
; PIC-Init.
|
||||
mov al, 00010011b ; ICW1, ICW4 benoetigt, Bit 2 egal,
|
||||
; Flankentriggerung
|
||||
out icw_1, al
|
||||
jmp short $+2 ; I/O-Delay
|
||||
mov al, 00001000b ; ICW2, auf INT 8 gemapped
|
||||
out icw_2_4, al
|
||||
jmp short $+2 ; I/O-Delay
|
||||
mov al, 00010001b ; ICW4, MCS-86, EOI, non-buffered,
|
||||
; fully nested
|
||||
out icw_2_4, al
|
||||
jmp short $+2 ; I/O-Delay
|
||||
mov al, 11111110b ; Kanal 0 am PIC demaskieren
|
||||
; PIT K1
|
||||
out ocw_1, al
|
||||
|
||||
; Interrupttabelle init.
|
||||
mov word [intab0], isr_servotimer ; Interrupttabelle (Timer K1)
|
||||
; initialisieren (Offset)
|
||||
mov [intab0 + 2], cs ; (Segmentadresse)
|
||||
sti ; ab jetzt Interrupts
|
||||
ret
|
||||
|
||||
isr_servotimer: ; Timer fuer Servo, besser exklusiv (CLI)
|
||||
push ax
|
||||
; ...
|
||||
; ...
|
||||
; ...
|
||||
|
||||
isr_servotimer_out:
|
||||
mov al, eoi ; EOI an PIC
|
||||
out ocw_2_3, al
|
||||
pop ax
|
||||
iret
|
|
@ -0,0 +1,67 @@
|
|||
org 100h
|
||||
cpu 8086
|
||||
|
||||
jmp start
|
||||
|
||||
; Variablen
|
||||
hsec db 0 ; Hundertstel
|
||||
|
||||
; Konstanten
|
||||
tc equ 18432 ; Zeitkonstante (1,8432 MHz Takt)
|
||||
intab equ 20h ; Adresse Interrupttabelle PIT, K1
|
||||
eoi equ 20h ; End Of Interrupt (EOI)
|
||||
clrscr equ 0 ; Clear Screen
|
||||
ascii equ 1 ; Funktion ASCII-Zeichenausgabe
|
||||
hexbyte equ 4 ; HEX-Byte Ausgabe
|
||||
conin equ 5 ; Console IN
|
||||
conout equ 6 ; Console OUT
|
||||
pitc equ 0a6h ; Steuerkanal PIT (Intervaltimer)
|
||||
pit1 equ 0a2h ; Kanal 1 PIT
|
||||
pic23 equ 0c0h ; PIC (Interruptcontroller), OCW2,3
|
||||
pic1 equ 0c2h ; PIC (Interruptcontroller), OCW1
|
||||
|
||||
start:
|
||||
|
||||
; Initialisierungen (Display, Sanduhr stellen etc.) erfolgen hier
|
||||
; ........
|
||||
; ........
|
||||
|
||||
call tinit ; Initialisierung PIT 8253 (Kanal 1)
|
||||
; und Interruptsystem
|
||||
|
||||
; Hintergrundprogramm
|
||||
|
||||
again:
|
||||
|
||||
; Der hier einzufügende Programmcode wird immer dann ausgeführt, wenn
|
||||
; die Interruptserviceroutine nicht läuft (Hintergrundprogramm).
|
||||
; Das wäre z.B. die Abfrage der Tastatur und die Manipulation der Statusbits.
|
||||
|
||||
jmp again
|
||||
|
||||
|
||||
tinit: cli ; Interrupts aus
|
||||
mov al, 01110110b ; Kanal 1, Mode 3, 16-Bit ZK
|
||||
out pitc, al ; Steuerkanal
|
||||
mov al, tc & 0ffh ; Low-Teil Zeitkonstante
|
||||
out pit1, al
|
||||
mov al, tc >> 8 ; High-Teil Zeitkonstante
|
||||
out pit1, al
|
||||
mov al, 11111110b ; Kanal 0 am PIC demaskieren
|
||||
out pic1, al
|
||||
mov word [intab], isr ; Interrupttabelle initialisieren
|
||||
mov [intab + 2], cs
|
||||
sti ; ab jetzt Interrupts
|
||||
ret
|
||||
|
||||
isr: push ax
|
||||
|
||||
; Interruptservice:
|
||||
; Hier ist z.B. der Programmcode einzufügen, der für die Zeitzählung und
|
||||
; Anzeige zuständig ist. Der gemeinsame Ausgang aus der ISR ist "isr1".
|
||||
|
||||
isr1: mov al, eoi ; EOI an PIC
|
||||
out pic23, al ; OCW
|
||||
pop ax
|
||||
iret
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
org 100h
|
||||
cpu 8086
|
||||
|
||||
jmp start
|
||||
|
||||
; Variablen
|
||||
divider db 0
|
||||
|
||||
; Konstanten
|
||||
tc equ 18432 ; Zeitkonstante (1,8432 MHz Takt)
|
||||
intab equ 20h ; Adresse Interrupttabelle PIT, K1
|
||||
eoi equ 20h ; End Of Interrupt (EOI)
|
||||
clrscr equ 0 ; Clear Screen
|
||||
ascii equ 1 ; Funktion ASCII-Zeichenausgabe
|
||||
hexbyte equ 4 ; HEX-Byte Ausgabe
|
||||
conin equ 5 ; Console IN
|
||||
conout equ 6 ; Console OUT
|
||||
pitc equ 0a6h ; Steuerkanal PIT (Intervaltimer)
|
||||
pit1 equ 0a2h ; Kanal 1 PIT
|
||||
pic23 equ 0c0h ; PIC (Interruptcontroller), OCW2,3
|
||||
pic1 equ 0c2h ; PIC (Interruptcontroller), OCW1
|
||||
|
||||
start:
|
||||
|
||||
; Initialisierungen (Display, Uhr stellen etc.) erfolgen hier
|
||||
; ........
|
||||
; ........
|
||||
|
||||
call tinit ; Initialisierung PIT 8253 (Kanal 1)
|
||||
; und Interruptsystem
|
||||
|
||||
; Hintergrundprogramm
|
||||
|
||||
again:
|
||||
|
||||
; Der hier einzufügende Programmcode wird immer dann ausgeführt, wenn
|
||||
; die Interruptserviceroutine nicht läuft (Hintergrundprogramm).
|
||||
; Das wäre z.B. die Abfrage der Tastatur und die Manipulation der Statusbits.
|
||||
|
||||
jmp again
|
||||
|
||||
|
||||
tinit: cli ; Interrupts aus
|
||||
mov al, 01110110b ; Kanal 1, Mode 3, 16-Bit ZK
|
||||
out pitc, al ; Steuerkanal
|
||||
mov al, tc & 0ffh ; Low-Teil Zeitkonstante
|
||||
out pit1, al
|
||||
mov al, tc >> 8 ; High-Teil Zeitkonstante
|
||||
out pit1, al
|
||||
mov al, 11111110b ; Kanal 0 am PIC demaskieren
|
||||
out pic1, al
|
||||
mov word [intab], isr ; Interrupttabelle initialisieren
|
||||
mov [intab + 2], cs
|
||||
sti ; ab jetzt Interrupts
|
||||
ret
|
||||
|
||||
isr: push ax
|
||||
inc byte [divider] ; Vorteiler durch 100
|
||||
cmp byte [divider], 100 ; fertig?
|
||||
jne isr1
|
||||
mov byte [divider], 0 ; von vorne
|
||||
|
||||
; Hier ist z.B. der Programmcode einzufügen, der für die Zeitzählung und
|
||||
; Anzeige zuständig ist. Der gemeinsame Ausgang aus der ISR ist "isr1".
|
||||
|
||||
isr1: mov al, eoi ; EOI an PIC
|
||||
out pic23, al ; OCW
|
||||
pop ax
|
||||
iret
|
Loading…
Reference in New Issue