diff --git a/20230615/ad-20230615.txt b/20230615/ad-20230615.txt new file mode 100644 index 0000000000000000000000000000000000000000..cdb1a84cc9a4d30028e5bf64a15a5c613ead2d91 --- /dev/null +++ b/20230615/ad-20230615.txt @@ -0,0 +1,89 @@ +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? diff --git a/20230615/crash.c b/20230615/crash.c new file mode 100644 index 0000000000000000000000000000000000000000..62d224512d44d55d34a532eb9fcc9ea14e443368 --- /dev/null +++ b/20230615/crash.c @@ -0,0 +1 @@ +main(){puts(0);} diff --git a/20230615/decode64-01.c b/20230615/decode64-01.c new file mode 100644 index 0000000000000000000000000000000000000000..a76fb018636ae0d9ead42dacf2b7b5c89394a7b1 --- /dev/null +++ b/20230615/decode64-01.c @@ -0,0 +1,28 @@ +#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; +} diff --git a/20230615/decode64-02.c b/20230615/decode64-02.c new file mode 100644 index 0000000000000000000000000000000000000000..b51651552abecbd4819b7638fc5abf49db6e8d96 --- /dev/null +++ b/20230615/decode64-02.c @@ -0,0 +1,29 @@ +#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; +} diff --git a/20230615/decode64-03.c b/20230615/decode64-03.c new file mode 100644 index 0000000000000000000000000000000000000000..da30d81325ecbdcc2dd087ce40b67dba4773f006 --- /dev/null +++ b/20230615/decode64-03.c @@ -0,0 +1,29 @@ +#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; +} diff --git a/20230615/decode64-04.c b/20230615/decode64-04.c new file mode 100644 index 0000000000000000000000000000000000000000..50b974b4e42cf879b88f3a7ce47dadc6463bc1e3 --- /dev/null +++ b/20230615/decode64-04.c @@ -0,0 +1,30 @@ +#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; +} diff --git a/20230615/decode64-05.c b/20230615/decode64-05.c new file mode 100644 index 0000000000000000000000000000000000000000..e20bcbeab56f1d526adb262905cdbc6e7df794e7 --- /dev/null +++ b/20230615/decode64-05.c @@ -0,0 +1,30 @@ +#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; +}