EX04 - Systèmes de nombres
Exercice 1 : Les nombres entiers non-signés
Convertir en binaire les nombres suivants :
- \(125_{10}\) (Base 10)
- \(0377_8\) (Base 8)
- \(0x\mathrm{ADE}1_{16}\) (Base 16)
Convertir en décimal les nombres suivants :
- \(0b10011000_2\) (Base 2)
- \(0177_8\) (Base 8)
- \(0x25\mathrm{E}1_{16}\) (Base 16)
Additionner les nombres binaires suivants et donner le résultat ainsi que l’état des flags C
et Z
. On considère des nombres sur 8 bits :
- \(0b10011000_2 + 0b10011000_2\)
- \(0b11111101_2 + 0b00000011_2\)
- \(0b00011000_2 + 0b10011100_2\)
Soustraire les nombres binaires suivants et donner le résultat ainsi que l’état des flags C
et Z
:
- \(0b10011000_2 - 0b10011000_2\)
- \(0b11111101_2 - 0b00000011_2\)
- \(0b00011000_2 - 0b10011100_2\)
Donner le résultat ainsi que l’état des flags C
et Z
pour les soustractions suivantes :
- \(125 - 128\)
- \(77 - 26\)
- \(254 - 254\)
- \(255 - 0\)
Exercice 2 : Les nombres entiers signés
Convertir en binaire les nombres suivants et indiquer l’état du flag N
:
- \(-125_{10}\) (Base 10)
- \(0271_8\) (Base 8)
- \(0x50\mathrm{F}1_{16}\) (Base 16)
Convertir en décimal les nombres suivants :
- \(0b10011000_2\) (Base 2)
- \(0177_8\) (Base 8)
- \(0x85\mathrm{E}1_{16}\) (Base 16)
Additionner les nombres binaires suivants et donner le résultat ainsi que l’état des flags V
, N
et Z
:
- \(0b10011000_2 + 0b10011000_2\)
- \(0b11111101_2 + 0b00000011_2\)
- \(0b00011000_2 + 0b10011100_2\)
Soustraire les nombres binaires suivants et donner le résultat ainsi que l’état des flags V
, N
et Z
:
- \(0b10011000_2 - 0b10011000_2\)
- \(0b11111101_2 - 0b00000011_2\)
- \(0b00011000_2 - 0b10011100_2\)
Donner le résultat ainsi que l’état des flags V
et N
et Z
pour les soustractions suivantes :
- \(127 - (-125)\)
- \(77 - (-26)\)
- \(-30 - (-34)\)
- \(55 - 66\)
Exercice 3 : Evaluation des flags
Pour les opérations suivantes, calculez :
- l’état des flags
N
,Z
,C
etV
- le résultat de l’opération si on interprète ce résultat comme un nombre signé
- le résultat de l’opération si on interprète ce résultat comme un nombre non signé
On considère des nombres sur 8 bits.
- \(128 - (-128)\)
- \(64 + (-128)\)
- \(228 - 128\)
- \(240 - (-16)\)
- \(0 - 0\)
- \(-7 + 249\)
- \(248 + (-128)\)
- \(128 + 0\)
- \(62 - 200\)
- \(-8 - (-96)\)
Exercice 4 : CPU à Accumulateur
Dans un exercice
précédent vous aviez
dévéloppé une CPU à accumulateur permettant d’effectuer des opérations
arithmetiques simples. A présent vous devrez l’étendre pour qu’elle soit capable
de calculer les flags Z
, C
, N
et V
ainsi qu’afficher le résultat de
l’opération sous forme signée et non-signée.
La classe doit avoir les éléments suivants :
- Une variable membre représentant l’accumulateur occupant 32 bits.
- Plusieurs variables représentant
Z
,C
,N
etV
. - Des méthodes pour les opérations suivantes :
load
(pour charger une valeur dans l’accumulateur),add
etsubtract
(pour effectuer ces opérations avec l’accumulateur et un autre opérande), etstore
(pour stocker la valeur de l’accumulateur dans une variable donnée).
- Une méthode
display
pour afficher la valeur actuelle de l’accumulateur, de la taille des registres, les valeurs maximales/minimales, les flags ainsi que le résultat (sous forme signée et non-signée).
Assurez-vous que votre classe encapsule correctement l’accumulateur et fournit
des méthodes d’accès appropriées. Vous pouvez également inclure une fonction
principale simple pour démontrer l’utilisation de votre classe AccumulatorCpu
.
Exemple d’utilisation :
#include <stdio.h>
#include <stdint.h>
int main() {
AccumulatorCpu acccpu(AccumulatorCpu::kRegister8bits);
printf("\n=============================== \n");
printf("Accumulator Computation results \n");
printf("=============================== \n");
acccpu.load(-7);
acccpu.add(207);
acccpu.display();
uint32_t uintResult;
acccpu.store(uintResult);
return 0;
}
AccumulatorCpu
est utilisée pour effectuer des
opérations arithmétiques de base et stocker les résultats. Le résultat obtenu
est le suivant :
===============================
Accumulator Computation results
===============================
Accumulator value: 0x00c8
Flags: N=1, Z=0, C=1, V=0
Accumulator value is (uint) : 200
Accumulator value is (int) : -56
Register Size = 8, Max Unsigned Value = 255, Max Signed Value = 127, Min Signed Value = -128
Ci-dessous vous trouverez une base avec laquelle vous pourrez démarrer votre implémentation.
class AccumulatorCpu {
public:
/* The supported register widths are 8 and 16 bits */
enum regSize {kRegister8bits = 8, kRegister16bits = 16};
AccumulatorCpu(regSize size) : accumulator(0), kMaxRegSize(size),
kUnsignMaxValue(1u << kMaxRegSize - 1),
kSignMaxValue ((1u << kMaxRegSize - 1) - 1),
kSignMinValue(-(1u << kMaxRegSize - 1))
{}
void load(uint32_t value) {
accumulator = value;
updateFlags();
}
void add(uint32_t value) {
// Set carry flag (C) if overflow occurs (i.e., sum exceeds 255) for
// 8-bit registers
// Check for overflow (V) in signed addition
accumulator = result;
updateFlags();
}
void substract(uint32_t value) {
uint32_t unsigned_x = unsignedValue(accumulator);
uint32_t unsigned_y = unsignedValue(value);
uint32_t unsigned_result = unsignedValue(x - y);
// Set carry flag (C) if no borrow occurs (i.e., result is non-negative)
// Check for overflow (V) in signed subtraction
accumulator = result;
updateFlags();
}
void store(uint32_t &target) const {
target = accumulator;
}
void display() const {
// You implementation here
}
private:
// Helper method to get the unsigned value in the 0-255 range (modulo 256)
// for 8-bit registers
uint32_t unsignedValue(uint32_t value) const {
return value % kUnsignMaxValue;
}
// Helper method to get the signed value, wrapping into the -128 to 127 range for an 8-bit size
int32_t signedValue(uint32_t value) const {
return (value < kSignMaxValue) ? static_cast<int32_t>(value) :
static_cast<int32_t>(value) - kUnsignMaxValue;
}
void updateFlags() {
// Update Zero flag (Z)
Z = (accumulator == 0) ? 1 : 0;
// Update Negative flag (N)
N = (accumulator & 1 << (kMaxRegSize - 1)) ? 1 : 0; // Check if the sign bit (bit 7) is set for 8-bit registers
}
uint32_t accumulator;
const uint32_t kMaxRegSize;
const uint32_t kUnsignMaxValue;
const uint32_t kSignMaxValue;
const int32_t kSignMinValue;
bool N, Z, C, V;
// whatever you need more...
};
Exercice 5 : Nombres réels
Représenter en hexadécimal sur 32 bits (simple précision) les valeurs réelles suivantes :
- \(1\,048\,576\)
- \(2048\)
- \(55.75\)
- \(5 \div 4096\)
- \(-25 \div 2\)