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