Da un Post di Mortebianca all'Assembly: Cronaca di una Follia Collettiva
Indice
- 1. Come tutto è cominciato: un codice "sospetto"
- 2. La correzione del precisino: Visual Basic .NET alla riscossa
- 3. Momento "adesso vi faccio vedere io": l'Assembly
- 4. L'impeto di imbecillità: il Linguaggio Muccastico
- 5. Un tocco di classe (e di Italia): il codice per l'ELEA 9003
1. Come tutto è cominciato: un codice "sospetto"
Tutto è partito da un tranquillo giorno sul canale Telegram di Mortebianca (che potete trovare qui). Morte pubblica un post con un piccolo snippet di codice, un'idea tanto semplice quanto... sbagliata.
L'intento era chiaro: ciclare una lista di nazioni e, se il nome conteneva la parola "socialist", cambiare la sua ideologia in "communist". Il problema? L'esecuzione. Questo era il codice "incriminato":
countries = [/* tutti i vari stati*/];
for each country in countries {
if (country.name = "%socialist%")
country.ideology = "communist";
}
Ora, per chi mastica un po' di programmazione, l'occhio cade subito su quel country.name = "%socialist%"
. Quello non è un confronto, ma un'assegnazione! E l'uso dei caratteri '%' per indicare una "contains" è, diciamo, fantasioso. È stato un attimo: la community si è scatenata.
2. La correzione del precisino: Visual Basic .NET alla riscossa
Sentendomi chiamato in causa dal sacro fuoco del debugging, ho deciso di fare il "precisino della situazione". Ho preso l'idea originale e l'ho trasformata in un codice funzionante, completo di un esempio pratico, usando il buon vecchio Visual Basic .NET. Un linguaggio un po' bistrattato, ma perfetto per mostrare la logica in modo chiaro.
Imports System
Imports System.Collections.Generic
Public Module Module1
Public Class Stato
Public Property Nome As String
Public Property Popolazione As Integer
Public Property Classificazione As String
Public Overrides Function ToString() As String
Return $"{{Nome: '{Me.Nome}', Popolazione: {Me.Popolazione}, Classificazione: '{Me.Classificazione}'}}"
End Function
End Class
Public Sub ClassificaStati(ByVal lista_stati As List(Of Stato))
For Each stato As Stato In lista_stati
If stato.Nome = "socialist" Then
stato.Classificazione = "comunista"
Else
stato.Classificazione = "non comunista"
End If
Next
End Sub
Public Sub Main()
Dim stati As New List(Of Stato) From {
New Stato With {.Nome = "socialist", .Popolazione = 1000000},
New Stato With {.Nome = "capitalist", .Popolazione = 5000000},
New Stato With {.Nome = "republic", .Popolazione = 3000000},
New Stato With {.Nome = "socialist", .Popolazione = 2500000}
}
ClassificaStati(stati)
For Each s As Stato In stati
Console.WriteLine(s)
Next
End Sub
End Module
Semplice, pulito e, soprattutto, funzionante. Ma la storia era appena iniziata.
3. Momento "adesso vi faccio vedere io": l'Assembly
Preso dall'entusiasmo della discussione nei commenti, ho pensato: "Perché non alzare il livello?". Così, per puro divertimento e per farmi un po' figo, ho riscritto la stessa logica in Assembly x86-64. Un salto carpiato dal comfort di un linguaggio ad alto livello alla gestione manuale della memoria e delle chiamate di sistema. Un'inutile e meravigliosa fatica.
; File: classifica.asm
; Per compilare ed eseguire su Linux (a 64-bit):
; nasm -f elf64 classifica.asm -o classifica.o
; ld classifica.o -o classifica
; ./classifica
section .data
; --- Stringhe costanti ---
socialist_target_str db "socialist", 0
comunista_str db "comunista", 0
non_comunista_str db "non comunista", 0
; --- Dati di output ---
separator db ": ", 2
newline db 10, 1
; --- Definizione della nostra "lista" di stati ---
STATO_SIZE equ 24
stati:
; Stato 1
dq state1_name
dq 1000000
dq 0
; Stato 2
dq state2_name
dq 5000000
dq 0
; Stato 3
dq state3_name
dq 3000000
dq 0
; Stato 4
dq state4_name
dq 2500000
dq 0
NUM_STATI equ ($ - stati) / STATO_SIZE
; Nomi degli stati
state1_name db "socialist", 0
state2_name db "capitalist", 0
state3_name db "republic", 0
state4_name db "socialist", 0
section .text
global _start
_start:
call classifica_stati
call stampa_risultati
mov rax, 60
xor rdi, rdi
syscall
classifica_stati:
mov rbx, stati
mov rcx, NUM_STATI
class_loop:
mov rsi, [rbx]
mov rdi, socialist_target_str
call strcmp
cmp rax, 0
je is_socialist
is_not_socialist:
mov rax, non_comunista_str
mov [rbx + 16], rax
jmp next_stato
is_socialist:
mov rax, comunista_str
mov [rbx + 16], rax
next_stato:
add rbx, STATO_SIZE
loop class_loop
ret
stampa_risultati:
mov rbx, stati
mov rcx, NUM_STATI
print_loop:
mov rsi, [rbx]
call strlen
mov rdx, rax
mov rsi, [rbx]
call print
mov rdx, 2
mov rsi, separator
call print
mov rsi, [rbx + 16]
call strlen
mov rdx, rax
mov rsi, [rbx + 16]
call print
mov rdx, 1
mov rsi, newline
call print
add rbx, STATO_SIZE
loop print_loop
ret
print:
mov rax, 1
mov rdi, 1
syscall
ret
strlen:
xor rax, rax
.loop:
cmp byte [rsi + rax], 0
je .done
inc rax
jmp .loop
.done:
ret
strcmp:
.loop:
mov al, [rsi]
mov dl, [rdi]
cmp al, dl
jne .done
cmp al, 0
je .done
inc rsi
inc rdi
jmp .loop
.done:
sub rax, rdx
ret
4. L'impeto di imbecillità: il Linguaggio Muccastico
A questo punto, la situazione era già degenerata in una gara di virtuosismi. E cosa c'è di più virtuoso che abbandonare completamente la logica e la sintassi umane? In un impeto di assoluta e totale imbecillità, ho riscritto tutto nel Linguaggio della Mucca. O "codice muccastico", come l'ho battezzato. Non chiedetemi cosa fa. Fa "Muu".
muuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuu muuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuu muuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuu muuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuu muuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuu muuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuu muuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuu muuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuu muuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuu muuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuu muuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuu muuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuu muuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuu muuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuu muuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuu muuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuu muuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuu muuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuu muuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuu muuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuu muuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuu muuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuu muuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuu muuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuu muuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuu muuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuu muuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuu muuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuu muuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuu muuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuu muuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuu muuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuu muuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuuuuu muuuuuuuuuuuuuuuuuu
5. Un tocco di classe (e di Italia): il codice per l'ELEA 9003
Per chiudere in bellezza e dare un tocco di orgoglio nazionale, ho deciso di fare un ultimo omaggio: riscrivere il programma per l'ELEA 9003. Per chi non lo sapesse, l'ELEA 9003 è un capolavoro dell'ingegneria italiana, uno dei primi computer a transistor del mondo, creato da Olivetti nel 1958. Un esemplare è ancora funzionante all'Istituto Fermi di Bibbiena. Il linguaggio è un dialetto dell'ALGOL 60, il PALGO. Un tuffo nel passato dell'informatica italiana.
begin
comment Questo è un programma per l'ELEA 9003 scritto in PALGO/ALGOL 60;
integer i; comment Dichiaro una variabile intera per il ciclo;
comment Dichiaro tre array paralleli per contenere 4 elementi ciascuno;
string array nomi, classificazioni [1:4];
integer array popolazioni [1:4];
comment Assegno i valori iniziali ai nostri dati;
nomi[1] := "socialist"; popolazioni[1] := 1000000;
nomi[2] := "capitalist"; popolazioni[2] := 5000000;
nomi[3] := "republic"; popolazioni[3] := 3000000;
nomi[4] := "socialist"; popolazioni[4] := 2500000;
comment Inizia il ciclo di classificazione.
Il ciclo 'for' va da 1 a 4;
for i := 1 step 1 until 4 do
begin
comment Controlla se il nome dello stato all'indice i è 'socialist';
if nomi[i] = "socialist" then
classificazioni[i] := "comunista"
else
classificazioni[i] := "non comunista";
end;
comment Ora, stampiamo i risultati. Le procedure di stampa (come 'stampa_stringa')
sarebbero state fornite dalla libreria standard della macchina;
for i := 1 step 1 until 4 do
begin
stampa_stringa(nomi[i]);
stampa_stringa(": ");
stampa_stringa(classificazioni[i]);
va_a_capo(); comment Va alla riga successiva sulla stampante;
end;
end
E così, da un semplice errore in un post su Telegram, è nata una splendida e inutile avventura attraverso decenni di storia della programmazione. Grazie, Morte, per lo spunto!