Aufgabe 5 - Bitweise Addition in C
Aufgabenstellung
Abschnitt betitelt „Aufgabenstellung“Gegeben ist das nachfolgend zu vervollständigende C-Programm für den Prozessor XC167 der Firma INFINEON.
Die beiden vorzeichenlosen Integerzahlen summand_1 und summand_2 sind mithilfe eines Scanf-Befehls und dem Formatierungsoperator “%u” mit Werten zu beschreiben. Nachfolgend ist eine Addition dieser beiden Zahlen durchzuführen und in der Variablen Summe abzulegen. Das Ergebnis ist dabei ausschließlich durch eine Addition der Bitstellen beider Summanden durchzuführen. Die Bitstellen des Summationsergebnisses sind einzeln auf dem Monitor mithilfe des Printf-Befehls auszugeben. Ebenfalls ist das Ergebnis als ganzzahliger vorzeichenloser Wert anzuzeigen.
Erläutern Sie mittels einiger Stichpunkte, wie Sie die bitweise Addition durchführen.
5 Pkt.
Ergänzen Sie das nachfolgende Programm an der markierten Stelle um Ihren Algorithmus.
#include <stdio.h> /* standard I/O .h-file */#include <reg167.h> /* special function register XC167 */
unsigned int summand_1, summand_2, summe;
...
void main (void){ /* initialize the serial interface */#ifndef MCB167 /* do not initialize if you use Monitor-166 */ P3 |= 0x0400; /* SET PORT 3.10 OUTPUT LATCH (TXD) */ DP3 |= 0x0400; /* SET PORT 3.10 DIRECTION CONTROL (TXD OUTPUT) */ DP3 &= 0xF7FF; /* RESET PORT 3.11 DIRECTION CONTROL (RXD INPUT) */ S0TIC = 0x80; /* SET TRANSMIT INTERRUPT FLAG */ S0RIC = 0x00; /* DELETE RECEIVE INTERRUPT FLAG */ S0BG = 0x40; /* SET BAUDRATE TO 9600 BAUD */ S0CON = 0x8011; /* SET SERIAL MODE */#endif .... /* hier Programmcode einfügen */}10 Pkt.
Anmerkung:
Abschnitt betitelt „Anmerkung:“Der Programmcode kann mit der C166-Entwicklungsumgebung der Firma armKEIL getestet werden. Der Programmcode zwischen #ifndef MCB167 und #endif vorab dient der Initialisierung der seriellen Schnittstelle des Prozessors zum Host-PC und ist unverändert zu belassen.
Für den Test des Programms ist keine C167-Hardware erforderlich, und der Simulator der Programmierumgebung kann genutzt werden.
Σ 15 Pkt. Gesamt: 100 Pkt.
a) Vorgehen bei der bitweisen Addition
Abschnitt betitelt „a) Vorgehen bei der bitweisen Addition“- Der XC167 verarbeitet hier 16-Bit-Werte. Deshalb werden die Bitstellen 0 bis 15 nacheinander bearbeitet.
- Vor dem ersten Durchlauf werden
summeund der Übertragcarryauf 0 gesetzt. - Mit
(summand >> i) & 1wird jeweils das Bit an der Positioniaus beiden Summanden gelesen. - Das Summenbit wird mit einer XOR-Verknüpfung gebildet:
sum_bit = bit_1 ^ bit_2 ^ carry. - Der neue Übertrag wird 1, wenn mindestens zwei der drei Eingangswerte 1 sind.
- Das fertige Summenbit wird wieder an seine ursprüngliche Position geschoben und mit einer ODER-Verknüpfung in
summeeingetragen. - Danach wird der neue Übertrag übernommen und die nächste Bitstelle bearbeitet.
- Zum Schluss werden die 16 Ergebnisbits von Bit 15 bis Bit 0 und anschließend der vorzeichenlose Dezimalwert ausgegeben.
Für den neuen Übertrag wird folgende bitweise Verknüpfung verwendet:
next_carry = (bit_1 & bit_2) | (bit_1 & carry) | (bit_2 & carry)Der Operator + wird zur Bildung des Ergebnisses nicht verwendet. Die Berechnung entspricht damit einem Volladdierer, der nacheinander auf alle 16 Bitstellen angewendet wird.
b) Ergänztes C-Programm
Abschnitt betitelt „b) Ergänztes C-Programm“#include <stdio.h> /* standard I/O .h-file */#include <reg167.h> /* special function register XC167 */
unsigned int summand_1, summand_2, summe;
void main (void){ unsigned int i; unsigned int bit_1, bit_2, sum_bit; unsigned int carry, next_carry;
/* initialize the serial interface */#ifndef MCB167 /* do not initialize if you use Monitor-166 */ P3 |= 0x0400; /* SET PORT 3.10 OUTPUT LATCH (TXD) */ DP3 |= 0x0400; /* SET PORT 3.10 DIRECTION CONTROL (TXD OUTPUT) */ DP3 &= 0xF7FF; /* RESET PORT 3.11 DIRECTION CONTROL (RXD INPUT) */ S0TIC = 0x80; /* SET TRANSMIT INTERRUPT FLAG */ S0RIC = 0x00; /* DELETE RECEIVE INTERRUPT FLAG */ S0BG = 0x40; /* SET BAUDRATE TO 9600 BAUD */ S0CON = 0x8011; /* SET SERIAL MODE */#endif
/* Beide Summanden einlesen */ printf("Ersten Summanden eingeben: "); scanf("%u", &summand_1);
printf("Zweiten Summanden eingeben: "); scanf("%u", &summand_2);
/* Ergebnis und ersten Uebertrag vorbereiten */ summe = 0; carry = 0;
/* Alle 16 Bitstellen von rechts nach links addieren */ for (i = 0; i < 16; i++) { /* Aktuelle Bits der beiden Summanden auslesen */ bit_1 = (summand_1 >> i) & 1; bit_2 = (summand_2 >> i) & 1;
/* Summenbit und Uebertrag fuer die naechste Stelle bilden */ sum_bit = bit_1 ^ bit_2 ^ carry;
next_carry = (bit_1 & bit_2) | (bit_1 & carry) | (bit_2 & carry);
/* Summenbit an Position i in das Ergebnis einsetzen */ summe |= sum_bit << i; carry = next_carry; }
/* Ergebnis zuerst binaer und danach als Dezimalwert ausgeben */ printf("\nErgebnisbits: "); for (i = 16; i > 0; i--) { printf("%u", (summe >> (i - 1)) & 1); }
printf("\nErgebnis als Dezimalwert: %u\n", summe);
/* Programm nach der Ausgabe anhalten */ while (1) { ; }}Die Initialisierung der seriellen Schnittstelle zwischen #ifndef MCB167 und #endif wurde unverändert übernommen.
Prüfung mit einem Beispiel
Abschnitt betitelt „Prüfung mit einem Beispiel“Für die Eingaben 13 und 7 entsteht folgender Ablauf an den ersten fünf Bitstellen:
| Bitstelle | Bit von 13 | Bit von 7 | Übertrag hinein | Summenbit | Übertrag hinaus |
|---|---|---|---|---|---|
| 0 | 1 | 1 | 0 | 0 | 1 |
| 1 | 0 | 1 | 1 | 0 | 1 |
| 2 | 1 | 1 | 1 | 1 | 1 |
| 3 | 1 | 0 | 1 | 0 | 1 |
| 4 | 0 | 0 | 1 | 1 | 0 |
Tabelle 5.1: Bitweise Prüfung der Addition 13 + 7 (eigene Berechnung).
Die Programmausgabe lautet damit:
Ergebnisbits: 0000000000010100Ergebnis als Dezimalwert: 20Das Ergebnis enthält die unteren 16 Bit. Bleibt nach Bit 15 noch ein Übertrag übrig, liegt ein Überlauf vor. Dieser zusätzliche Übertrag kann nicht mehr in der vorgegebenen 16-Bit-Variablen summe gespeichert werden.