Un po' di effetto dimagrante (da 240 a 224 bytes) del post precedente mettendoci anche un po' di colore (certo..la palette non e' bellissima)
Ho tolto anche la dipendenza dai registri a 32 bit che non era necessaria
----------------------------------------------------------------------
org 100h ; serve solo per DOS per fare i file .COM
section .data
a: dq -2.0 ; minimo reale della finestra
b: dq -1.5 ; minimo immaginario della finestra
bb: dq -1.5 ; asdasd
da: dq 0.0078125 ; incremento parte reale ((1.2-(-2))/320px delta_a
db: dq 0.015 ; incremento parte immaginaria ((1.5-1.5))/200px delta_b
limite: dq 4.0 ; condizione di fuga
section .text
global _start ;must be declared for using gcc
_start:
; inizializza il modo 13h 320x200x8bpp (256 colori) SOLO PER DOS CON VGA
mov al, 13h
int 10h
; fa puntare direttamente alla memoria video SOLO PER DOS
mov ax, 0a000h
mov es, ax
mov di,319 ; dimensione dell'asse reale in pixel sullo schermo
loop_reale:
mov dx,199 ; dimensione dell'asse immaginario in pixel sullo schermo
; calcola a = a + delta_a
fstp st0
fld qword [a] ; mette a in st0
fld qword [da] ; mette l'incremento di a in st1
fadd st0,st1 ; a+da
fstp qword [a] ; mette il risultato in a
loop_immaginario:
; calcola b = b + delta_b
;fstp st0 ; resetta lo stack della FPU
fld qword [b] ; mette b in st0
fld qword [db] ; mette l'incremento di b in st1
fadd st0,st1 ; b+db
fstp qword [b] ; mette il risultato in b
; pulisce tutto lo stack del 387 (8 registri portati a zero)
;inizia la fase di calcolo
fstp st0
fld qword [a] ; mette a nello stack
fld qword [b] ; mette b nello stack
push cx ; salva il registro cx
mov cx,255 ; in cx ci sara' il contatore dei cicli di iterazioni di calcolo. Si parte da 256
fldZ ; mette stack st3 = 0. Sara' utilizzato come parte reale z.r = 0
fldZ ; mette stack st2 = 0. Sara' utilizzato come parte immaginaria z.i = 0
fldZ ; mette stack st1 = 0. Sara' utilizzato come parte reale quadrata z.r^2 = 0
fldZ ; mette stack st0 = 0. Sara' utilizzato come parte immaginaria quadrata z.i^2 = 0
l1: ; inizia il loop di calcolo piu' interno
fsubp st1,st0 ; sottrae z.i^2- e lo mette nello stack come st0.
fadd qword [a] ; aggiunge a ad st0
fstp st3 ; prende il valore di st3 con pop
fmulp st1,st0 ; moltiplica st0 ed st1 z.r*z.i
fadd st0,st0 ; moltiplica 2*st0 facendolo come una somma st0+st0
fadd qword [b] ; aggiunge ad st0 b ovvero 2*z.r+z.i+b
fld st1 ; mette st1 in st0 ovvero z.r
fmul st0,st0 ; quadrato di z.r
fld st1 ; mette st1 in st0 ovvero z.i
fmul st0,st0 ; quadrato di z.i
fld st1
fadd st0,st1 ; somma i due quadrati z.r^2+z.i^2
fcomp qword [limite]; compara st0 con il limite di calcolo 4
fstsw ax ; passa il valore di st0 al registro ax
sahf ; mette AH nelle flags
jae fine ; se ax e' sopra il valore di 4 allora esci dal ciclo di calcolo
dec ecx ; decrementa il contatore della iterazioni di calcolo
jnz l1 ; se ecx non e' zero continua il calcolo saltando alla label l1
fine:
ffree st5
ffree st4
ffree st3
ffree st2
ffree st1
ffree st0
; stampa il colore a seconda del valore di cx
push di
push bx
push dx
mov bx,dx ; in dx c'e' la coordinata schermo immaginaria
imul bx,320 ; viene moltiplicata per 320
add bx,di ; in cx c'e' la coordinata schermo reale
mov di,bx ; ha calcolato la posizione in memoria
mov [es:di],cl
pop dx
pop bx
pop di
pop cx
ritorna:
;controlla se siamo alla fine di un loop immaginario
dec dx
cmp dx,0
jnz loop_immaginario
; resetta la variabile immaginaria
fld qword [bb]
fstp qword [b]
;controlla se siamo alla fine di un loop reale
dec di
cmp di,0
jnz loop_reale
;esce dal programma
; aspetta la pressione di un tasto (SOLO DOS)
xor ah, ah
int 16h
; Rimette in modalita' testuale (SOLO DOS)
mov ax, 0003h
int 10h
ret
venerdì 29 aprile 2016
giovedì 28 aprile 2016
Mandelbrot Mode 13h
Ed ora qualcosa di completamente inutile...Mandelbrot in modo 13h della VGA. Il codice di base e' quello del precedente post riadattato per la visualizzazione grafica a 320x200x256 colori
Visto che per questa visualizzazione si usa l'accesso diretto alla memoria video ed un formato di eseguibile sotto DOS si deve usare DosBox oppure FreeDos in macchina virtuale (non si puo' invece usare DosEmu perche' di fatto questo programma non emula il processore ma si appoggia sul sistema sottostante per cui ogni gestione diretta della memoria crea conflitto con il sottostante sistema operativo)
-------------------------------------------------------------------------
org 100h ; serve solo per DOS per fare i file .COM
section .data
a: dq -2.0 ; minimo reale della finestra
b: dq -1.5 ; minimo immaginario della finestra
bb: dq -1.5 ; asdasd
da: dq 0.0078125 ; incremento parte reale ((1.2-(-2))/320px delta_a
db: dq 0.015 ; incremento parte immaginaria ((1.5-1.5))/200px delta_b
limite: dq 4.0 ; condizione di fuga
cicli: dd 255 ; numero di cicli di iterazione per ogni punto
section .text
global _start ;serve a gcc
_start:
; inizializza il modo 13h 320x200x8bpp (256 colori) SOLO PER DOS CON VGA
mov al, 13h
int 10h
; fa puntare direttamente alla memoria video SOLO PER DOS
mov ax, 0a000h
mov es, ax
mov di,319 ; dimensione dell'asse reale in pixel sullo schermo
loop_reale:
mov dx,199 ; dimensione dell'asse immaginario in pixel sullo schermo
; calcola a = a + delta_a
fstp st0
fld qword [a] ; mette a in st0
fld qword [da] ; mette l'incremento di a in st1
fadd st0,st1 ; a+da
fstp qword [a] ; mette il risultato in a
loop_immaginario:
; calcola b = b + delta_b
;fstp st0 ; resetta lo stack della FPU
fld qword [b] ; mette b in st0
fld qword [db] ; mette l'incremento di b in st1
fadd st0,st1 ; b+db
fstp qword [b] ; mette il risultato in b
;inizia la fase di calcolo
fstp st0
fld qword [a] ; mette a nello stack
fld qword [b] ; mette b nello stack
push ecx ; salva il registro ecx
mov ecx,[cicli] ; in ecx ci sara' il contatore dei cicli di iterazioni di calcolo. Si parte da 256
fldZ ; mette stack st3 = 0. Sara' utilizzato come parte reale z.r = 0
fldZ ; mette stack st2 = 0. Sara' utilizzato come parte immaginaria z.i = 0
fldZ ; mette stack st1 = 0. Sara' utilizzato come parte reale quadrata z.r^2 = 0
fldZ ; mette stack st0 = 0. Sara' utilizzato come parte immaginaria quadrata z.i^2 = 0
l1: ; inizia il loop di calcolo piu' interno
fsubp st1,st0 ; sottrae z.i^2- e lo mette nello stack come st0.
fadd qword [a] ; aggiunge a ad st0
fstp st3 ; prende il valore di st3 con pop
fmulp st1,st0 ; moltiplica st0 ed st1 z.r*z.i
fadd st0,st0 ; moltiplica 2*st0 facendolo come una somma st0+st0
fadd qword [b] ; aggiunge ad st0 b ovvero 2*z.r+z.i+b
fld st1 ; mette st1 in st0 ovvero z.r
fmul st0,st0 ; quadrato di z.r
fld st1 ; mette st1 in st0 ovvero z.i
fmul st0,st0 ; quadrato di z.i
fld st1
fadd st0,st1 ; somma i due quadrati z.r^2+z.i^2
fcomp qword [limite]; compara st0 con il limite di calcolo 4
fstsw ax ; passa il valore di st0 al registro ax
sahf ; mette AH nelle flags
jae fine ; se ax e' sopra il valore di 4 allora esci dal ciclo di calcolo
dec ecx ; decrementa il contatore della iterazioni di calcolo
jnz l1 ; se ecx non e' zero continua il calcolo saltando alla label l1
fine:
ffree st5
ffree st4
ffree st3
ffree st2
ffree st1
ffree st0
cmp ecx,0 ; controlla se si e' raggiunto il limite dei cicli di iterazione
je putpixel ; se e' zero stampa uno spazio
pop ecx
ritorna:
;controlla se siamo alla fine di un loop immaginario
dec dx
cmp dx,0
jnz loop_immaginario
; resetta la variabile immaginaria
fld qword [bb]
fstp qword [b]
;controlla se siamo alla fine di un loop reale
dec di
cmp di,0
jnz loop_reale
;esce dal programma
; aspetta la pressione di un tasto (SOLO DOS)
xor ah, ah
int 16h
; Rimette in modalita' testuale (SOLO DOS)
mov ax, 0003h
int 10h
ret
putpixel: ; scrive un pixel direttamente sulla memoria VGA
push di
push bx
push dx
mov bx,dx ; in dx c'e' la coordinata schermo immaginaria
imul bx,320 ; viene moltiplicata per 320
add bx,di ; in cx c'e' la coordinata schermo reale
mov di,bx ; ha calcolato la posizione in memoria
mov dl,7
mov [es:di],dl
pop dx
pop bx
pop di
jmp ritorna
-------------------------------------------------------------------------
il programma compilato con nasm (disponibile sia per Linux che per Dos) e' lungo 240 bytes
Per correggere gli errori non si puo' fare debug sotto Linux perche' ddd (ovviamente) non riconosce il formato .COM. Per questo motivo mi sono ricostruito un ambiente di sviluppo in Freedos in macchina virtuale sotto VMWare
Visto che non e' banalissimo usare Freedos un po' di appunti su come installarlo su VMWare. Per prima cosa di monta la .iso del Cd di Freedos e si formatta il disco C:. Al termine l'installer richiede il riavvio del sistema ma ci si trova di fronte alla schermata sottostante perche' VMWare e' ripartito dal disco fisso dove non e' ancora stato installato il sistema
Da qui in poi l'installazione e' banale...rimane il problema di installare il software in un sistema come il DOS che ha pochissima confidenza con le chiavette USB ed il TCP/IP.La soluzione che ho trovato piu' semplice e' stata quella di inserire tutto il software DOS che mi serviva (Volkov Commander, Nasm e Turbo Debugger) in una cartella, convertire la cartella in un file .iso con AnyToIso ed inserire il file .iso del CD virtuale di VMWare.
Fatta partire la macchina virtuale, dal prompt di Dos, si digita (vedi questo link)
devload uide.sys /N3 /D:CDROM01
il Cdrom sara' su D: e si possono copiare il file su C:. I file copiati saranno tutti read-only per cui si deve usare il programma ATTRIB per togliere il flag
Visto che per questa visualizzazione si usa l'accesso diretto alla memoria video ed un formato di eseguibile sotto DOS si deve usare DosBox oppure FreeDos in macchina virtuale (non si puo' invece usare DosEmu perche' di fatto questo programma non emula il processore ma si appoggia sul sistema sottostante per cui ogni gestione diretta della memoria crea conflitto con il sottostante sistema operativo)
-------------------------------------------------------------------------
org 100h ; serve solo per DOS per fare i file .COM
section .data
a: dq -2.0 ; minimo reale della finestra
b: dq -1.5 ; minimo immaginario della finestra
bb: dq -1.5 ; asdasd
da: dq 0.0078125 ; incremento parte reale ((1.2-(-2))/320px delta_a
db: dq 0.015 ; incremento parte immaginaria ((1.5-1.5))/200px delta_b
limite: dq 4.0 ; condizione di fuga
cicli: dd 255 ; numero di cicli di iterazione per ogni punto
section .text
global _start ;serve a gcc
_start:
; inizializza il modo 13h 320x200x8bpp (256 colori) SOLO PER DOS CON VGA
mov al, 13h
int 10h
; fa puntare direttamente alla memoria video SOLO PER DOS
mov ax, 0a000h
mov es, ax
mov di,319 ; dimensione dell'asse reale in pixel sullo schermo
loop_reale:
mov dx,199 ; dimensione dell'asse immaginario in pixel sullo schermo
; calcola a = a + delta_a
fstp st0
fld qword [a] ; mette a in st0
fld qword [da] ; mette l'incremento di a in st1
fadd st0,st1 ; a+da
fstp qword [a] ; mette il risultato in a
loop_immaginario:
; calcola b = b + delta_b
;fstp st0 ; resetta lo stack della FPU
fld qword [b] ; mette b in st0
fld qword [db] ; mette l'incremento di b in st1
fadd st0,st1 ; b+db
fstp qword [b] ; mette il risultato in b
;inizia la fase di calcolo
fstp st0
fld qword [a] ; mette a nello stack
fld qword [b] ; mette b nello stack
push ecx ; salva il registro ecx
mov ecx,[cicli] ; in ecx ci sara' il contatore dei cicli di iterazioni di calcolo. Si parte da 256
fldZ ; mette stack st3 = 0. Sara' utilizzato come parte reale z.r = 0
fldZ ; mette stack st2 = 0. Sara' utilizzato come parte immaginaria z.i = 0
fldZ ; mette stack st1 = 0. Sara' utilizzato come parte reale quadrata z.r^2 = 0
fldZ ; mette stack st0 = 0. Sara' utilizzato come parte immaginaria quadrata z.i^2 = 0
l1: ; inizia il loop di calcolo piu' interno
fsubp st1,st0 ; sottrae z.i^2- e lo mette nello stack come st0.
fadd qword [a] ; aggiunge a ad st0
fstp st3 ; prende il valore di st3 con pop
fmulp st1,st0 ; moltiplica st0 ed st1 z.r*z.i
fadd st0,st0 ; moltiplica 2*st0 facendolo come una somma st0+st0
fadd qword [b] ; aggiunge ad st0 b ovvero 2*z.r+z.i+b
fld st1 ; mette st1 in st0 ovvero z.r
fmul st0,st0 ; quadrato di z.r
fld st1 ; mette st1 in st0 ovvero z.i
fmul st0,st0 ; quadrato di z.i
fld st1
fadd st0,st1 ; somma i due quadrati z.r^2+z.i^2
fcomp qword [limite]; compara st0 con il limite di calcolo 4
fstsw ax ; passa il valore di st0 al registro ax
sahf ; mette AH nelle flags
jae fine ; se ax e' sopra il valore di 4 allora esci dal ciclo di calcolo
dec ecx ; decrementa il contatore della iterazioni di calcolo
jnz l1 ; se ecx non e' zero continua il calcolo saltando alla label l1
fine:
ffree st5
ffree st4
ffree st3
ffree st2
ffree st1
ffree st0
cmp ecx,0 ; controlla se si e' raggiunto il limite dei cicli di iterazione
je putpixel ; se e' zero stampa uno spazio
pop ecx
ritorna:
;controlla se siamo alla fine di un loop immaginario
dec dx
cmp dx,0
jnz loop_immaginario
; resetta la variabile immaginaria
fld qword [bb]
fstp qword [b]
;controlla se siamo alla fine di un loop reale
dec di
cmp di,0
jnz loop_reale
;esce dal programma
; aspetta la pressione di un tasto (SOLO DOS)
xor ah, ah
int 16h
; Rimette in modalita' testuale (SOLO DOS)
mov ax, 0003h
int 10h
ret
putpixel: ; scrive un pixel direttamente sulla memoria VGA
push di
push bx
push dx
mov bx,dx ; in dx c'e' la coordinata schermo immaginaria
imul bx,320 ; viene moltiplicata per 320
add bx,di ; in cx c'e' la coordinata schermo reale
mov di,bx ; ha calcolato la posizione in memoria
mov dl,7
mov [es:di],dl
pop dx
pop bx
pop di
jmp ritorna
-------------------------------------------------------------------------
il programma compilato con nasm (disponibile sia per Linux che per Dos) e' lungo 240 bytes
Per correggere gli errori non si puo' fare debug sotto Linux perche' ddd (ovviamente) non riconosce il formato .COM. Per questo motivo mi sono ricostruito un ambiente di sviluppo in Freedos in macchina virtuale sotto VMWare
Turbo Debugger in FreeDos |
Visto che non e' banalissimo usare Freedos un po' di appunti su come installarlo su VMWare. Per prima cosa di monta la .iso del Cd di Freedos e si formatta il disco C:. Al termine l'installer richiede il riavvio del sistema ma ci si trova di fronte alla schermata sottostante perche' VMWare e' ripartito dal disco fisso dove non e' ancora stato installato il sistema
Si deve entrare nel Bios di VMware ed impostare l'ordine di avvio dei dispositivi...peccato che la schermata e' velocissima ed e' praticamente impossibile trovare l'attimo giusto per premere ESC all'avvio. La soluzione piu' semplice e' quella di editare il file in Documenti/My Virtual Machines/MS-DOS/MS_DOS.vmx ed aggiungere la riga
bios.bootDelay = "5000"
per ritardare il boot di 5 secondi ed avere il tempo di premere ESC
Fatta partire la macchina virtuale, dal prompt di Dos, si digita (vedi questo link)
devload uide.sys /N3 /D:CDROM01
shsucdx /D:CDROM01
il Cdrom sara' su D: e si possono copiare il file su C:. I file copiati saranno tutti read-only per cui si deve usare il programma ATTRIB per togliere il flag
mercoledì 27 aprile 2016
Mandelbrot Assembler su Linux in FPU x87 32 bit
Grazie all'aiuto di internet (il nucleo del codice di calcolo e' stato ripreso riadattandolo da questo link) sono riuscito nel mio scopo utilizzando codice x87 per i calcoli in virgola mobile ed il terminale per la visualizzazione (l'accesso diretto alla memoria video del modo 13h della VGA e' possibile solo sotto DOS)
Il codice e' piuttosto generale e permette di generare immagini di qualsiasi grandezza (basta agire sui registri di e dx) e con una finestra di visualizzazione qualsiasi (basta agire sui parametri a,b,bb,da e db) e con una profondita' di calcolo modificabile (variabile cicli)
Il codice e' totalmente commentato
Per calcolare il valore di da e di db si prende la dimensione della finestra per esempio -1.5 e +1.5, si somma (dimensione 3) e si divide per la dimensione in pixel dello schermo da quindi assume il valore di 3/80=0.0375
Esempio con finestra (-1.5,-2/1.5,2) 80x80 pixels
------------------------------------------------------
section .data
a: dq -1.5 ; minimo reale della finestra
b: dq -2.0 ; minimo immaginario della finestra
bb: dq -2.0 ; minimo immaginario della finestra (serve per resettare la variabile)
da: dq 0.0375 ; incremento parte reale ((2-(-2))/80px delta_a
db: dq 0.05 ; incremento parte immaginaria ((1.5-1.5))/80px delta_b
limite: dq 4.0 ; condizione di fuga
cicli: dd 255 ; numero di cicli di iterazione per ogni punto
stella: db '*',0 ; stella (dentro insieme Mandelbrot)
spazio: db ' ',0 ; spazio (fuori insiemeMandelbrot)
acapo: db 0x0a,0
section .text
global _start ;serve a gcc
_start:
mov di,80 ; dimensione dell'asse reale in pixel sullo schermo
loop_reale:
mov dx,80 ; dimensione dell'asse immaginario in pixel sullo schermo
; calcola a = a + delta_a
fstp st0
fld qword [a] ; mette a in st0
fld qword [da] ; mette l'incremento di a in st1
fadd st0,st1 ; a+da
fstp qword [a] ; mette il risultato in a
loop_immaginario:
; calcola b = b + delta_b
fld qword [b] ; mette b in st0
fld qword [db] ; mette l'incremento di b in st1
fadd st0,st1 ; b+db
fstp qword [b] ; mette il risultato in b
;inizia la fase di calcolo
fstp st0
fld qword [a] ; mette a nello stack
fld qword [b] ; mette b nello stack
push ecx ; salva il registro ecx
mov ecx,[cicli] ; in ecx ci sara' il contatore dei cicli di iterazioni di calcolo. Si parte da 255
fldZ ; mette stack st3 = 0. Sara' utilizzato come parte reale z.r = 0
fldZ ; mette stack st2 = 0. Sara' utilizzato come parte immaginaria z.i = 0
fldZ ; mette stack st1 = 0. Sara' utilizzato come parte reale quadrata z.r^2 = 0
fldZ ; mette stack st0 = 0. Sara' utilizzato come parte immaginaria quadrata z.i^2 = 0
l1: ; inizia il loop di calcolo piu' interno
fsubp st1,st0 ; sottrae z.i^2- e lo mette nello stack come st0.
fadd qword [a] ; aggiunge a ad st0
fstp st3 ; prende il valore di st3 con pop
fmulp st1,st0 ; moltiplica st0 ed st1 z.r*z.i
fadd st0,st0 ; moltiplica 2*st0 facendolo come una somma st0+st0
fadd qword [b] ; aggiunge ad st0 b ovvero 2*z.r+z.i+b
fld st1 ; mette st1 in st0 ovvero z.r
fmul st0,st0 ; quadrato di z.r
fld st1 ; mette st1 in st0 ovvero z.i
fmul st0,st0 ; quadrato di z.i
fld st1
fadd st0,st1 ; somma i due quadrati z.r^2+z.i^2
fcomp qword [limite]; compara st0 con il limite di calcolo 4
fstsw ax ; passa il valore di st0 al registro ax
sahf ; mette AH nelle flags
jae fine ; se ax e' sopra il valore di 4 allora esci dal ciclo di calcolo
dec ecx ; decrementa il contatore della iterazioni di calcolo
jnz l1 ; se ecx non e' zero continua il calcolo saltando alla label l1
fine:
ffree st5 ; ripulisce lo stack della FPU
ffree st4
ffree st3
ffree st2
ffree st1
ffree st0
;fase di stampa sul terminale
push edx
mov eax,4 ; chiamata di sistema (sys_write)
mov ebx,1 ; File descriptor 1 - standard output
mov edx,1 ;
cmp ecx,0 ; controlla se si e' raggiunto il limite dei cicli di iterazione
je stampa_stella ; se e' zero stampa uno spazio
mov ecx,spazio ; punta alla variabile spazio
jmp salta
stampa_stella:
mov ecx,stella ; punta alla variabile stella
salta:
int 80h ; Chiama il kernel
pop edx
pop ecx
ritorna:
;controlla se siamo alla fine di un loop immaginario
dec dx
cmp dx,0
jnz loop_immaginario
; resetta la variabile immaginaria ovvero la riporta al valore minimo
fld qword [bb]
fstp qword [b]
; stampa un ritorno a capo se siamo arrivati al margine della finestra
mov eax,4 ; (sys_write)
mov ebx,1 ; File descriptor 1 - standard output
mov ecx,acapo ;
mov edx,1
int 80h ; Chiama il kernel
;controlla se siamo alla fine di un loop reale
dec di
cmp di,0
jnz loop_reale
; Ritorna al sistema operativo
mov eax,1
mov ebx,0
int 80h
------------------------------------------------------
L'eseguibile compilato e privato del codice di debug e' lungo attorno ai 650 bytes (sicuramente si puo' fare di meglio sia come scrittura del codice che come compattezza dell'eseguibile)
E per concludere il ricordo del primo insieme di Mandelbrot mai visualizzato (direttamente sul calcolatore di Benoit Mandelbrot)
martedì 26 aprile 2016
venerdì 22 aprile 2016
Assemby x86 e dissemblare in Linux
Un po' di appunti per compilare e decompilare in Assembler sotto Linux
La sintassi di nasm e' simile a quella di TASM ma ci sono alcuni dettagli per cui non e' sempre possibile compilare codice vecchio senza modifiche
Prima di tutto GEdit non ha preimpostata la colorazione della sintassi dei file .asm ma si puo' rimediare con i comandi
wget http://www.carminebenedetto.net/_downloads/asm-intel.lang
sudo cp asm-intel.lang /usr/share/gtksourceview-3.0/language-specs/
per compilare il codice (compreso della tabella dei simboli per il debug)
nasm -f elf -F dwarf mand_linux.asm
ld mand_linux.o -o mand_linux
per rimuovere i codici di debug (ed ottenere un eseguibile nettamente piu' snello) si puo' aggiungere in fase di link lo switch --strip-all come segue
ld mand_linux.o -o mand_linux --strip-all
per compilare codice a 32 bit su un sistema operativo a 64 bit
nasm -f elf -F dwarf mand_linux.asm
ld -m elf_i386 mand_linux.o -o mand_linux
con nasm si possono compilare anche eseguibili DOS (i vecchi file .COM)
nasm -f bin -o mand_dos.com mand_dos.asm
dosbox mand_dos.com -exit
per compilare codice DOS in formato COM si deve aggiungere in testa al codice la linea
org 100h
il programma DOS puo' essere verificato con DOSBOX
dosbox programma.com -exit
Per decompilare o fare debugging, al posto del complicato gdb, puo' essere molto comodo usare ddd, una IDE di gdb in cui si puo' fare debug step-by-step con breakpoint (tasto destro sulla riga di codice), watch delle variabili e dei valori dei registri del processore
E' anche possibile editare direttamente il codice e ricompilare senza uscire da ddd (questa funzione mi ha creato qualche problema a dire il vero perche' la finestra di debug non sempre e' aggiornata con gli aggiornamenti del codice)
Nel caso di core dump del codice si puo' eseguire
gdb file_eseguibile file_core
seguito dal comando backtrace per capire dove si e' generato il segmentation fault. All'interno di ddd si puo' lanciare l'esecuzione (senza breakpoint), attendere il core dump e poi fare il backtrace direttamente dalla IDE
La sintassi di nasm e' simile a quella di TASM ma ci sono alcuni dettagli per cui non e' sempre possibile compilare codice vecchio senza modifiche
Prima di tutto GEdit non ha preimpostata la colorazione della sintassi dei file .asm ma si puo' rimediare con i comandi
wget http://www.carminebenedetto.net/_downloads/asm-intel.lang
sudo cp asm-intel.lang /usr/share/gtksourceview-3.0/language-specs/
per compilare il codice (compreso della tabella dei simboli per il debug)
nasm -f elf -F dwarf mand_linux.asm
ld mand_linux.o -o mand_linux
per rimuovere i codici di debug (ed ottenere un eseguibile nettamente piu' snello) si puo' aggiungere in fase di link lo switch --strip-all come segue
ld mand_linux.o -o mand_linux --strip-all
per compilare codice a 32 bit su un sistema operativo a 64 bit
nasm -f elf -F dwarf mand_linux.asm
ld -m elf_i386 mand_linux.o -o mand_linux
con nasm si possono compilare anche eseguibili DOS (i vecchi file .COM)
nasm -f bin -o mand_dos.com mand_dos.asm
dosbox mand_dos.com -exit
per compilare codice DOS in formato COM si deve aggiungere in testa al codice la linea
org 100h
il programma DOS puo' essere verificato con DOSBOX
dosbox programma.com -exit
Per decompilare o fare debugging, al posto del complicato gdb, puo' essere molto comodo usare ddd, una IDE di gdb in cui si puo' fare debug step-by-step con breakpoint (tasto destro sulla riga di codice), watch delle variabili e dei valori dei registri del processore
E' anche possibile editare direttamente il codice e ricompilare senza uscire da ddd (questa funzione mi ha creato qualche problema a dire il vero perche' la finestra di debug non sempre e' aggiornata con gli aggiornamenti del codice)
Nel caso di core dump del codice si puo' eseguire
gdb file_eseguibile file_core
seguito dal comando backtrace per capire dove si e' generato il segmentation fault. All'interno di ddd si puo' lanciare l'esecuzione (senza breakpoint), attendere il core dump e poi fare il backtrace direttamente dalla IDE
giovedì 21 aprile 2016
Stampa cartacea di un libro di Google Play??
Avendo del credito sul mio account Google generato da Google Rewards ho deciso di spenderlo in un libro di apprendimento di musica. Ovviamente, come tutti i musicisti hanno provato sulla loro pelle, e' necessario avere la copia cartacea per suonare...qualsiasi altro tipo di supporto e' scomodo, illeggibile, difficilmente personalizzabile con annotazioni etc. etc
Dopo avere comprato il libro lo ho trovato disponibile sul mio dispositivo mobile (senza peraltro diritto di recesso per non ho ben chiara quale normativa)...ok ma come lo stampo???
Sono andato sul desktop ed ho puntato su Google Books, nella mia libreria era presenta l'acquisto e sull'icona dell'ingranaggio in alto a destra compariva la dicitura Download PDF...perfetto...non troppo.
Il file in download era un file .ascm che ho scoperto di essere poco piu' che un link da dare in pasto Adobe Digital Edition per poter scaricare il Pdf vero
Facciamo anche questa..installato Adobe Digital Edition viene scaricato il pdf (su Mac viene messo in /home/Documenti/Digital Editions/) ma si tratta di un file con DRM che non permette ne' la selezione del testo ne' la stampa cartacea.
Esistono a questo punto dei programmi che permettono di rimuovere il DRM di Adobe (di cui non forniro' il link) e potrei finalmente stampare il libro.....ma e' normale una storia del genere per un libro legittimamente acquistato???
Mi sa che continuero' ad acquistare libri cartacei da Amazon e dalla libreria fisica (sempre che queste non spariscano e che amplino un po' il loro catalogo..)
Dopo avere comprato il libro lo ho trovato disponibile sul mio dispositivo mobile (senza peraltro diritto di recesso per non ho ben chiara quale normativa)...ok ma come lo stampo???
Sono andato sul desktop ed ho puntato su Google Books, nella mia libreria era presenta l'acquisto e sull'icona dell'ingranaggio in alto a destra compariva la dicitura Download PDF...perfetto...non troppo.
Il file in download era un file .ascm che ho scoperto di essere poco piu' che un link da dare in pasto Adobe Digital Edition per poter scaricare il Pdf vero
Facciamo anche questa..installato Adobe Digital Edition viene scaricato il pdf (su Mac viene messo in /home/Documenti/Digital Editions/) ma si tratta di un file con DRM che non permette ne' la selezione del testo ne' la stampa cartacea.
Esistono a questo punto dei programmi che permettono di rimuovere il DRM di Adobe (di cui non forniro' il link) e potrei finalmente stampare il libro.....ma e' normale una storia del genere per un libro legittimamente acquistato???
Mi sa che continuero' ad acquistare libri cartacei da Amazon e dalla libreria fisica (sempre che queste non spariscano e che amplino un po' il loro catalogo..)
mercoledì 20 aprile 2016
Leap Motion SDK
Mi sono comprato per circa 20 euro il Leap Motion su un e-commerce cinese (su Amazon costa piu' del doppio) con il dubbio che non fosse l'originale ma un clone.
Il dispositivo funziona perferttamente con i driver originali ed anche la confezione sembra corretta
Il sito web di Leap Motion riporta il pacchetto .deb per l'installazione sotto Linux e le istruzioni per Ubuntu ma funziona tranquillamente anche su Debian. Peraltro anche i requisiti minimi del sistema sono abbondantemente sorvradimesionati....il dispositivo funziona anche su un Centrino 1GHz (anche se si inizia a notare il ritardo)
dpkg -i Leap-*-.x86.deb
Dal punto di vista hardware il Leap Motion e' costituito da una coppia di telecamere ad infrarossi ad alta velocita' (200 fotogrammi al secondo) ed un illuminatore ad infrarossi. Vista la ridotta potenza dell'illuminatore il raggio d'azione del sensore e' inferiore al metro ma la risoluzione e' stimata a circa 0.7 cm
Non ho capito bene se il sensore usa la visione stereoscopica per determinare la terza dimensione oppure si tratta solo di una coppia di telecamere ed il lavoro di interpretazione e' demandato al PC e' connesso (aggiornamento: leggendo la documentazione tecnica tutto il lavoro di riconoscimento viene fatto dal PC, il sensore manda solo coppie di immagini, peraltro il Leap Motion viene riconosciuto nel syslog come un dispositivo video come una qualunque webcam)
Un aspetto da non sottovalutare e' la disponibilita' dell'SDK che si puo' scaricare direttamente da questo link.Sono previste librerie per C, Python e Unity
Ho provato ad usare l'esempio per Python (nella directory /samples) ma non riusciva a importare il modulo Leap. Ho riscritto parte del codice, evidenziato in giallo per fare il puntamento alle directory in modo corretto.
(versione ridotta con la sola posizione di pitch, roll e yaw)
sys.path += ["/usr/lib/Leap","../lib/x86","../lib"]
import Leap
from Leap import CircleGesture, KeyTapGesture, ScreenTapGesture, SwipeGesture
class SampleListener(Leap.Listener):
finger_names = ['Thumb', 'Index', 'Middle', 'Ring', 'Pinky']
bone_names = ['Metacarpal', 'Proximal', 'Intermediate', 'Distal']
state_names = ['STATE_INVALID', 'STATE_START', 'STATE_UPDATE', 'STATE_END']
def on_init(self, controller):
print "Initialized"
def on_connect(self, controller):
print "Connected"
# Enable gestures
controller.enable_gesture(Leap.Gesture.TYPE_CIRCLE);
controller.enable_gesture(Leap.Gesture.TYPE_KEY_TAP);
controller.enable_gesture(Leap.Gesture.TYPE_SCREEN_TAP);
controller.enable_gesture(Leap.Gesture.TYPE_SWIPE);
def on_disconnect(self, controller):
# Note: not dispatched when running in a debugger.
print "Disconnected"
def on_exit(self, controller):
print "Exited"
def on_frame(self, controller):
# Get the most recent frame and report some basic information
frame = controller.frame()
# Get hands
for hand in frame.hands:
handType = "Left hand" if hand.is_left else "Right hand"
print " %s, id %d, position: %s" % (
handType, hand.id, hand.palm_position)
# Get the hand's normal vector and direction
normal = hand.palm_normal
direction = hand.direction
# Calculate the hand's pitch, roll, and yaw angles
print " pitch: %f degrees, roll: %f degrees, yaw: %f degrees" % (
direction.pitch * Leap.RAD_TO_DEG,
normal.roll * Leap.RAD_TO_DEG,
direction.yaw * Leap.RAD_TO_DEG)
def main():
# Create a sample listener and controller
listener = SampleListener()
controller = Leap.Controller()
# Have the sample listener receive events from the controller
controller.add_listener(listener)
# Keep this process running until Enter is pressed
print "Press Enter to quit..."
try:
sys.stdin.readline()
except KeyboardInterrupt:
pass
finally:
# Remove the sample listener when done
controller.remove_listener(listener)
if __name__ == "__main__":
main()
--------------------------------------------------------------------------
La cosa incredibile e' la quantita' di informazioni fornita.
Per esempio il sensore riesce a distinguere
1) mano destra da mano sinistra
2) vettore normale della mano
3) yaw, pitch e roll della posizione della mano
4) direzione del braccio, direzione del polso
5) per ogni dito vengono forniti 4 valori per ciascuna delle giunzioni delle ossa
--------------------------------------------------------------------------
Frame id: 81414, timestamp: 1461155610589896, hands: 1, fingers: 5, tools: 0, gestures: 0
Right hand, id 19, position: (33.206, 101.55, 31.0056)
pitch: -0.360167 degrees, roll: -19.586099 degrees, yaw: -15.937854 degrees
Arm direction: (-0.539341, -0.159729, -0.8268), wrist position: (56.3493, 103.269, 80.5455), elbow position: (201.971, 146.396, 303.781)
Thumb finger, id: 190, length: 52.116371mm, width: 20.250000mm
Bone: Metacarpal, start: (27.9765, 103.101, 92.2079), end: (27.9765, 103.101, 92.2079), direction: (0, 0, 0)
Bone: Proximal, start: (27.9765, 103.101, 92.2079), end: (-6.82482, 100.813, 56.4951), direction: (0.697175, 0.0458273, 0.715435)
Bone: Intermediate, start: (-6.82482, 100.813, 56.4951), end: (-30.6533, 99.3269, 32.1536), direction: (0.698872, 0.0435907, 0.713917)
Bone: Distal, start: (-30.6533, 99.3269, 32.1536), end: (-50.3944, 104.308, 20.6123), direction: (0.843508, -0.212845, 0.493145)
Index finger, id: 191, length: 58.807510mm, width: 19.342800mm
Bone: Metacarpal, start: (38.8333, 118.553, 77.8819), end: (4.48218, 112.147, 13.1405), direction: (0.46692, 0.0870757, 0.880002)
Bone: Proximal, start: (4.48218, 112.147, 13.1405), end: (-13.782, 110.943, -25.7277), direction: (0.42512, 0.0280223, 0.904703)
Bone: Intermediate, start: (-13.782, 110.943, -25.7277), end: (-25.9697, 93.3597, -36.9743), direction: (0.504241, 0.727484, 0.465305)
Bone: Distal, start: (-25.9697, 93.3597, -36.9743), end: (-31.1777, 77.3075, -34.3053), direction: (0.304817, 0.939512, -0.156218)
Middle finger, id: 192, length: 67.006439mm, width: 18.997200mm
Bone: Metacarpal, start: (49.2811, 115.897, 71.9318), end: (25.0349, 106.497, 7.19131), direction: (0.347527, 0.134729, 0.92794)
Bone: Proximal, start: (25.0349, 106.497, 7.19131), end: (15.6093, 104.469, -40.035), direction: (0.19555, 0.0420621, 0.979791)
Bone: Intermediate, start: (15.6093, 104.469, -40.035), end: (2.5615, 85.8319, -57.0945), direction: (0.458841, 0.655411, 0.599918)
Bone: Distal, start: (2.5615, 85.8319, -57.0945), end: (-6.32149, 69.2732, -56.8969), direction: (0.472701, 0.88116, -0.0105194)
Ring finger, id: 193, length: 64.428482mm, width: 18.077040mm
Bone: Metacarpal, start: (59.6432, 110.65, 67.9288), end: (46.5165, 98.9206, 7.8132), direction: (0.209559, 0.187246, 0.9597)
Bone: Proximal, start: (46.5165, 98.9206, 7.8132), end: (49.952, 104.128, -36.4287), direction: (-0.0768931, -0.116561, 0.990202)
Bone: Intermediate, start: (49.952, 104.128, -36.4287), end: (42.4103, 90.7847, -59.5039), direction: (0.272243, 0.48169, 0.832981)
Bone: Distal, start: (42.4103, 90.7847, -59.5039), end: (33.5572, 75.4563, -65.4834), direction: (0.473833, 0.820404, 0.320031)
Pinky finger, id: 194, length: 50.510735mm, width: 16.057440mm
Bone: Metacarpal, start: (68.5105, 99.5173, 67.8996), end: (64.7404, 88.1882, 11.157), direction: (0.065018, 0.19538, 0.97857)
Bone: Proximal, start: (64.7404, 88.1882, 11.157), end: (75.9784, 92.3616, -22.108), direction: (-0.317824, -0.11803, 0.940775)
Bone: Intermediate, start: (75.9784, 92.3616, -22.108), end: (74.1183, 84.4117, -39.8812), direction: (0.0951014, 0.406461, 0.908705)
Bone: Distal, start: (74.1183, 84.4117, -39.8812), end: (66.4641, 71.7476, -48.7209), direction: (0.444062, 0.734713, 0.51284)
--------------------------------------------------------------------------
Il dispositivo funziona perferttamente con i driver originali ed anche la confezione sembra corretta
Il sito web di Leap Motion riporta il pacchetto .deb per l'installazione sotto Linux e le istruzioni per Ubuntu ma funziona tranquillamente anche su Debian. Peraltro anche i requisiti minimi del sistema sono abbondantemente sorvradimesionati....il dispositivo funziona anche su un Centrino 1GHz (anche se si inizia a notare il ritardo)
dpkg -i Leap-*-.x86.deb
Dal punto di vista hardware il Leap Motion e' costituito da una coppia di telecamere ad infrarossi ad alta velocita' (200 fotogrammi al secondo) ed un illuminatore ad infrarossi. Vista la ridotta potenza dell'illuminatore il raggio d'azione del sensore e' inferiore al metro ma la risoluzione e' stimata a circa 0.7 cm
Non ho capito bene se il sensore usa la visione stereoscopica per determinare la terza dimensione oppure si tratta solo di una coppia di telecamere ed il lavoro di interpretazione e' demandato al PC e' connesso (aggiornamento: leggendo la documentazione tecnica tutto il lavoro di riconoscimento viene fatto dal PC, il sensore manda solo coppie di immagini, peraltro il Leap Motion viene riconosciuto nel syslog come un dispositivo video come una qualunque webcam)
Un aspetto da non sottovalutare e' la disponibilita' dell'SDK che si puo' scaricare direttamente da questo link.Sono previste librerie per C, Python e Unity
Ho provato ad usare l'esempio per Python (nella directory /samples) ma non riusciva a importare il modulo Leap. Ho riscritto parte del codice, evidenziato in giallo per fare il puntamento alle directory in modo corretto.
(versione ridotta con la sola posizione di pitch, roll e yaw)
--------------------------------------------------------------------------
import os, sys, thread, time,inspect,thread
sys.path += ["/usr/lib/Leap","../lib/x86","../lib"]
import Leap
from Leap import CircleGesture, KeyTapGesture, ScreenTapGesture, SwipeGesture
class SampleListener(Leap.Listener):
finger_names = ['Thumb', 'Index', 'Middle', 'Ring', 'Pinky']
bone_names = ['Metacarpal', 'Proximal', 'Intermediate', 'Distal']
state_names = ['STATE_INVALID', 'STATE_START', 'STATE_UPDATE', 'STATE_END']
def on_init(self, controller):
print "Initialized"
def on_connect(self, controller):
print "Connected"
# Enable gestures
controller.enable_gesture(Leap.Gesture.TYPE_CIRCLE);
controller.enable_gesture(Leap.Gesture.TYPE_KEY_TAP);
controller.enable_gesture(Leap.Gesture.TYPE_SCREEN_TAP);
controller.enable_gesture(Leap.Gesture.TYPE_SWIPE);
def on_disconnect(self, controller):
# Note: not dispatched when running in a debugger.
print "Disconnected"
def on_exit(self, controller):
print "Exited"
def on_frame(self, controller):
# Get the most recent frame and report some basic information
frame = controller.frame()
# Get hands
for hand in frame.hands:
handType = "Left hand" if hand.is_left else "Right hand"
print " %s, id %d, position: %s" % (
handType, hand.id, hand.palm_position)
# Get the hand's normal vector and direction
normal = hand.palm_normal
direction = hand.direction
# Calculate the hand's pitch, roll, and yaw angles
print " pitch: %f degrees, roll: %f degrees, yaw: %f degrees" % (
direction.pitch * Leap.RAD_TO_DEG,
normal.roll * Leap.RAD_TO_DEG,
direction.yaw * Leap.RAD_TO_DEG)
def main():
# Create a sample listener and controller
listener = SampleListener()
controller = Leap.Controller()
# Have the sample listener receive events from the controller
controller.add_listener(listener)
# Keep this process running until Enter is pressed
print "Press Enter to quit..."
try:
sys.stdin.readline()
except KeyboardInterrupt:
pass
finally:
# Remove the sample listener when done
controller.remove_listener(listener)
if __name__ == "__main__":
main()
--------------------------------------------------------------------------
Per esempio il sensore riesce a distinguere
1) mano destra da mano sinistra
2) vettore normale della mano
3) yaw, pitch e roll della posizione della mano
4) direzione del braccio, direzione del polso
5) per ogni dito vengono forniti 4 valori per ciascuna delle giunzioni delle ossa
--------------------------------------------------------------------------
Frame id: 81414, timestamp: 1461155610589896, hands: 1, fingers: 5, tools: 0, gestures: 0
Right hand, id 19, position: (33.206, 101.55, 31.0056)
pitch: -0.360167 degrees, roll: -19.586099 degrees, yaw: -15.937854 degrees
Arm direction: (-0.539341, -0.159729, -0.8268), wrist position: (56.3493, 103.269, 80.5455), elbow position: (201.971, 146.396, 303.781)
Thumb finger, id: 190, length: 52.116371mm, width: 20.250000mm
Bone: Metacarpal, start: (27.9765, 103.101, 92.2079), end: (27.9765, 103.101, 92.2079), direction: (0, 0, 0)
Bone: Proximal, start: (27.9765, 103.101, 92.2079), end: (-6.82482, 100.813, 56.4951), direction: (0.697175, 0.0458273, 0.715435)
Bone: Intermediate, start: (-6.82482, 100.813, 56.4951), end: (-30.6533, 99.3269, 32.1536), direction: (0.698872, 0.0435907, 0.713917)
Bone: Distal, start: (-30.6533, 99.3269, 32.1536), end: (-50.3944, 104.308, 20.6123), direction: (0.843508, -0.212845, 0.493145)
Index finger, id: 191, length: 58.807510mm, width: 19.342800mm
Bone: Metacarpal, start: (38.8333, 118.553, 77.8819), end: (4.48218, 112.147, 13.1405), direction: (0.46692, 0.0870757, 0.880002)
Bone: Proximal, start: (4.48218, 112.147, 13.1405), end: (-13.782, 110.943, -25.7277), direction: (0.42512, 0.0280223, 0.904703)
Bone: Intermediate, start: (-13.782, 110.943, -25.7277), end: (-25.9697, 93.3597, -36.9743), direction: (0.504241, 0.727484, 0.465305)
Bone: Distal, start: (-25.9697, 93.3597, -36.9743), end: (-31.1777, 77.3075, -34.3053), direction: (0.304817, 0.939512, -0.156218)
Middle finger, id: 192, length: 67.006439mm, width: 18.997200mm
Bone: Metacarpal, start: (49.2811, 115.897, 71.9318), end: (25.0349, 106.497, 7.19131), direction: (0.347527, 0.134729, 0.92794)
Bone: Proximal, start: (25.0349, 106.497, 7.19131), end: (15.6093, 104.469, -40.035), direction: (0.19555, 0.0420621, 0.979791)
Bone: Intermediate, start: (15.6093, 104.469, -40.035), end: (2.5615, 85.8319, -57.0945), direction: (0.458841, 0.655411, 0.599918)
Bone: Distal, start: (2.5615, 85.8319, -57.0945), end: (-6.32149, 69.2732, -56.8969), direction: (0.472701, 0.88116, -0.0105194)
Ring finger, id: 193, length: 64.428482mm, width: 18.077040mm
Bone: Metacarpal, start: (59.6432, 110.65, 67.9288), end: (46.5165, 98.9206, 7.8132), direction: (0.209559, 0.187246, 0.9597)
Bone: Proximal, start: (46.5165, 98.9206, 7.8132), end: (49.952, 104.128, -36.4287), direction: (-0.0768931, -0.116561, 0.990202)
Bone: Intermediate, start: (49.952, 104.128, -36.4287), end: (42.4103, 90.7847, -59.5039), direction: (0.272243, 0.48169, 0.832981)
Bone: Distal, start: (42.4103, 90.7847, -59.5039), end: (33.5572, 75.4563, -65.4834), direction: (0.473833, 0.820404, 0.320031)
Pinky finger, id: 194, length: 50.510735mm, width: 16.057440mm
Bone: Metacarpal, start: (68.5105, 99.5173, 67.8996), end: (64.7404, 88.1882, 11.157), direction: (0.065018, 0.19538, 0.97857)
Bone: Proximal, start: (64.7404, 88.1882, 11.157), end: (75.9784, 92.3616, -22.108), direction: (-0.317824, -0.11803, 0.940775)
Bone: Intermediate, start: (75.9784, 92.3616, -22.108), end: (74.1183, 84.4117, -39.8812), direction: (0.0951014, 0.406461, 0.908705)
Bone: Distal, start: (74.1183, 84.4117, -39.8812), end: (66.4641, 71.7476, -48.7209), direction: (0.444062, 0.734713, 0.51284)
--------------------------------------------------------------------------
fra le altre coste e' possibile impostare anche il riconoscimento delle gesture
Iscriviti a:
Post (Atom)
LLama download checkpoint
Oltre a scaricare i dati per usare un modello puo' essere necessario effettuare un retrain di un modello ed in questo caso non si posson...
-
In questo post viene indicato come creare uno scatterplot dinamico basato da dati ripresi da un file csv (nel dettaglio il file csv e' c...
-
La scheda ESP32-2432S028R monta un Esp Dev Module con uno schermo TFT a driver ILI9341 di 320x240 pixels 16 bit colore.Il sito di riferiment...
-
Questo post e' a seguito di quanto gia' visto nella precedente prova Lo scopo e' sempre il solito: creare un sistema che permet...