Skip to content
Snippets Groups Projects
Commit 01cd748b authored by Peter Gerwinski's avatar Peter Gerwinski
Browse files

Beispiele und Notizen 15.6.2023

parent 151f6c80
No related branches found
No related tags found
No related merge requests found
Addition langer Zahlen, 01.06.2023, 17:37:20
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Siehe: longadd-*.c, longadd-*.s, sum-*.s
Das Addieren mit Übertrag ("carry") ist in Assembler-Sprache einfacher(!)
als in C.
Addieren mit Übertrag in C mit der GNU Compiler Collection (GCC):
https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html
Aufgabe: Addieren beliebig langer Zahlen. Siehe: 20230601/longadd-10.c
~~~~~~~
Hinweis für die Initialisierung langer Zahlen:
Um einen String mit einer Dezimalzahl in eine lange Zahl umzuwandeln,
braucht man bereits funktionierende Langzahlarithmetik.
Bei Hexadezimalzahlen kann man jeweils eine Hex-Ziffer in 4 Bit umwandeln.
--> Verwenden Sie durchgehend hexadezimale Notation.
Das ist viel einfacher, als wenn Sie dezimal rechnen.
Problem: Es funktioniert für unsigned, aber nicht für signed.
Beispiel: 16384 - 1 auf 4-Bit-Rechenwerk
Binär: 0010 0000 0000 0000 \
+ 1111 1111 1111 1111 } Rechnung vollständig vorzeichenlos
-1----------------- /
1001 1111 1111 1111 = 16383
Lösungsansatz in Assembler (Pseudo-Code):
z[n] = x[n] + y[n]; // Symbolische Notation für:
// lange Zahlen, abgespeichert in Arrays, korrekt addieren
load reg_x <-- &x
load reg_y <-- &y
load reg_z <-- &z
load reg_c <-- 0
load reg_n <-- n
load reg_a <-- *reg_x
load reg_b <-- *reg_y
add reg_a += reg_b // Carry-Flag nicht berücksichtigen, aber ggf. neu setzen
loop:
store *reg_z <-- reg_a
push status // Carry-Flag (und andere Flags) auf Stack sichern
compare reg_c < reg_n
jump_if_greater_or_equal end
add reg_c += 1
add reg_x += 8 // 8 Bytes für 64-Bit-Zahlen
add reg_y += 8
add reg_z += 8
pop status // Carry-Flag zurückholen (Ergebnis der Addition x + y)
load reg_a <-- *reg_x
load reg_b <-- *reg_y
adc reg_a += reg_b // Carry-Flag berücksichtigen und ggf. neu setzen
jmp loop
end:
pop status // Das Status-Register liegt noch auf dem Stack. Aufräumen.
(Ohne Gewähr.;-)
2 Register einsparen:
x[n] =+ y[n]; // Symbolische Notation für:
// lange Zahlen, abgespeichert in Arrays, korrekt addieren
load reg_x <-- &x
load reg_y <-- &y
load reg_c <-- n
load reg_a <-- *reg_x
load reg_b <-- *reg_y
add reg_a += reg_b // Carry-Flag nicht berücksichtigen, aber ggf. neu setzen
loop:
store *reg_x <-- reg_a
push status // Carry-Flag (und andere Flags) auf Stack sichern
sub reg_c -= 1
compare reg_c == 0
jump_if_zero end
add reg_x += 8 // 8 Bytes für 64-Bit-Zahlen
add reg_y += 8
pop status // Carry-Flag zurückholen (Ergebnis der Addition x + y)
load reg_a <-- *reg_x
load reg_b <-- *reg_y
adc reg_a += reg_b // Carry-Flag berücksichtigen und ggf. neu setzen
jmp loop
end:
pop status // Das Status-Register liegt noch auf dem Stack. Aufräumen.
Dateisysteme, 15.06.2023, 17:34:47
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Wie finde ich die Adresse von FAT1, FAT2, Root-Verzeichnis und den Clustern selbst?
main(){puts(0);}
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <string.h>
uint64_t decode (char *s)
{
uint64_t a = 0;
for (int i = strlen (s) - 1; i >= 0; i--)
{
a <<= 4;
char c = s[i];
if (c >= '0' && c <= '9')
a |= c - '0';
else if (c >= 'A' && c <= 'F')
a |= c - 'A' + 10;
else if (c >= 'a' && c <= 'f')
a |= c - 'a' + 10;
}
return a;
}
int main (void)
{
uint64_t a = decode ("affe123deadbeef");
printf ("%016" PRIx64 "\n", a);
return 0;
}
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <string.h>
uint64_t decode (char *s)
{
uint64_t a = 0;
for (int i = strlen (s) - 1; i >= 0; i--)
{
char c = s[i];
char b = 0;
if (c >= '0' && c <= '9')
b = c - '0';
else if (c >= 'A' && c <= 'F')
b = c - 'A' + 10;
else if (c >= 'a' && c <= 'f')
b = c - 'a' + 10;
a |= b << 4 * i;
}
return a;
}
int main (void)
{
uint64_t a = decode ("affe123deadbeef");
printf ("%016" PRIx64 "\n", a);
return 0;
}
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <string.h>
uint64_t decode (char *s)
{
uint64_t a = 0;
for (int i = strlen (s) - 1; i >= 0; i--)
{
char c = s[i];
uint64_t b = 0;
if (c >= '0' && c <= '9')
b = c - '0';
else if (c >= 'A' && c <= 'F')
b = c - 'A' + 10;
else if (c >= 'a' && c <= 'f')
b = c - 'a' + 10;
a |= b << 4 * i;
}
return a;
}
int main (void)
{
uint64_t a = decode ("affe123deadbeef");
printf ("%016" PRIx64 "\n", a);
return 0;
}
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <string.h>
uint64_t decode (char *s)
{
uint64_t a = 0;
int lm1 = strlen (s) - 1;
for (int i = lm1; i >= 0; i--)
{
char c = s[i];
uint64_t b = 0;
if (c >= '0' && c <= '9')
b = c - '0';
else if (c >= 'A' && c <= 'F')
b = c - 'A' + 10;
else if (c >= 'a' && c <= 'f')
b = c - 'a' + 10;
a |= b << 4 * (lm1 - i);
}
return a;
}
int main (void)
{
uint64_t a = decode ("affe123deadbeef");
printf ("%016" PRIx64 "\n", a);
return 0;
}
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <string.h>
uint64_t decode (char *s)
{
uint64_t a = 0;
int lm1 = strlen (s) - 1;
for (int i = 0; i <= lm1; i++)
{
char c = s[i];
uint64_t b = 0;
if (c >= '0' && c <= '9')
b = c - '0';
else if (c >= 'A' && c <= 'F')
b = c - 'A' + 10;
else if (c >= 'a' && c <= 'f')
b = c - 'a' + 10;
a |= b << 4 * (lm1 - i);
}
return a;
}
int main (void)
{
uint64_t a = decode ("affe123deadbeef");
printf ("%016" PRIx64 "\n", a);
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment