PDA

View Full Version : [assembler] Addio? Gara di "opere d'arti"


amedeoviscido
22-06-2008, 13:58
Secondo me l'assembler è un linguaggio non è necessariamente caduto in disuso; certo serve solo per scrivere codice per particolari macchine, perlopiù embedded, ma chi l'ha utilizzato a fondo direi che si è reso conto che si possono fare delle vere e proprie opere d'arte!

Propongo una gara: proponete un frammento di codice, spiegando quello che fa, e come lo avete risolto in modo più elegante possibile.

Vi faccio un esempio, comincio io!

Calcolare il valore assoluto del registro AX (assembler x86)

Codice "normale"

CMP AX,0
JGE non_negativo
NEG AX
non_negativo:


Questo pezzetto calcola il valore assoluto di AX in 6 byte. Guardate questa soluzione (che però sporca il registro DX):


CWD
XOR AX,DX
SUB AX,DX


Sublime, direi...

variabilepippo
22-06-2008, 14:52
Sublime, direi...


È l'approccio standard con il quale viene calcolato il valore assoluto... ;)

Codice a 32-bit:


cdq
xor eax, edx
sub eax, edx

amedeoviscido
22-06-2008, 15:14
Beh dipende, quando ne venni a capo (a tredici anni) mi sentii molto figo!!!

DanieleC88
22-06-2008, 16:05
Vabbe', anche lo scambio di due valori usando tre XOR è fighissimo, ma non mi sembra il caso di fare una gara... :D

amedeoviscido
22-06-2008, 17:35
Lo conosco anch'io ma posta lo stesso, un pò per figaggine. In molti non ci capiranno niente!!!

DanieleC88
22-06-2008, 18:00
Vabbe', è facile come concetto, è il linguaggio in sé che è ostico. Vado un po' a memoria.

MIPS:
.data
a: .word 5
b: .word 10
newline: .asciiz "\n"

.text
.globl main
main:
lw $t0, a
lw $t1, b
xor $t2, $t0, $t1
xor $t0, $t0, $t2
xor $t1, $t1, $t2
move $a0, $t0
li $v0, 1
syscall
lw $a0, newline
li $v0, 4
syscall
move $a0, $t1
li $v0, 1
syscall
lw $a0, newline
li $v0, 4
syscall

li $v0, 10
syscall

x86 (NASM):
[section .data]
a dw 5
b dw 10
format db "%d\n%d\n\0"

[section .text]
[extern printf]
[global main]
main:
mov eax, [a]
mov ebx, [b]
mov edx, ebx
xor edx, eax
xor eax, edx
xor ebx, edx
push ebx
push eax
push word [format]
call printf

Non fate caso agli errori.

amedeoviscido
22-06-2008, 22:24
Vogliamo la stampa!!!

compariamo la difficoltà di console.writeline(x) e del listato assembly!!!

DanieleC88
22-06-2008, 22:38
Aggiornato, ma non contate troppo sull'affidabilità del codice.

amedeoviscido
23-06-2008, 00:00
Eh ma che è quella printf... io volevo la scrittura diretta nella memoria, vi ricordo l'indirizzo B800:0000 ..

variabilepippo
23-06-2008, 00:17
io volevo la scrittura diretta nella memoria, vi ricordo l'indirizzo B800:0000


A che pro scrivere codice compatibile soltanto con MS-DOS in pieno 2008? ;) Se non si crea codice a 16 bit un accesso diretto alla memoria verrebbe bloccato dal sistema operativo.

cdimauro
23-06-2008, 07:47
Ma poi a B800:0000 ci sta la CGA. Quindi non funzionerebbe con la Hercules (B000:0000). :D

A parte questo, io preferivo A000:0000, ma in mode 13h... :cool:

amedeoviscido
23-06-2008, 08:36
Grande è vero!!! Però non ti dovevi dimenticare di settare la palette!

cdimauro
23-06-2008, 08:50
Di default c'era una palette già settata con una buona scelta di colori.

Comunque era prassi raderla e impostarne una ad hoc. ;)

DanieleC88
23-06-2008, 10:35
Esattamente, mi hanno anticipato gli altri, scrivere direttamente nella memoria solo per far vedere tre XOR mi sembrava un po' una cosa da spaccone, oltre che totalmente inutile... :p

gugoXX
23-06-2008, 17:17
Alcuni trucchi funzionano e vanno bene anche oggi.
altri come lo scambio con gli XOR invece erano gia' poco performanti allora, ed utili solo in alcuni casi particolari.

Le moltiplicazioni p.es. potrebbero essere utili anche oggi
Le seguenti p.es. sono tutte senza stalli.


X2 lea eax,[eax+eax]
X3 lea eax,[eax+eax*2]
X4 lea eax,[eax*4]
X5 lea eax,[eax+eax*4]
X8 lea eax,[eax*8]
X9 lea eax,[eax+eax*8]