; Assemblatore NASM 2.07
; calcola il numero di cifre decimali '2' presenti tra due numeri A e B
; compresi gli estremi. stampa anche la sequenza dei numeri.
; esempio tra i numeri 2001 e 20012 ci sono 14 cifre '2'
; usa registri a 16 bits
;
; 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012
;
global _start
section .data
buffer resb 16
num_a dw 2001
num_b dw 2012
section .text
_start:
mov si,[num_a] ; mette numero iniziale in SI
mov di,[num_b] ; mette il numero finale in DI
mov cx,0 ; uso CX come contatore delle cifre '2'
loop1:
mov ax,si
call print_ax ; stampo il numero in AX
loop2:
xor dx,dx
mov bx,10
div bx
cmp dx,2
jne not_due
inc cx
not_due:
cmp ax,0
jne loop2
inc si
cmp si,di
jbe loop1
; ora in CX ho il numero di '2' e lo stampo
mov ax,cx
call print_ax
exit:
mov eax, 01h ; exit()
xor ebx, ebx ; errno
int 80h
print_ax
push eax
push ecx
push edx
mov edx,buffer
call bin2dec16
mov byte [buffer+ecx],0ah ; aggiunge new-line
mov byte [buffer+ecx+1],0 ; make ASCIIZ
call printasciiz
pop edx
pop ecx
pop eax
ret
; FUNCTION: bin2dec16
; converte un numero binario a 16 bit in una stringa ASCII decimale
; Parametri:
; AX = numero da stampare
; EDX = indirizzo del buffer ASCII (5 cifre)
; Return:
; ECX = lunghezza della strinag
bin2dec16:
push eax
push ebx
push edx
push esi
mov esi,edx
mov ecx,0 ; contatore cifre significative
mov bx,10 ; divisore
.loop1
xor dx,dx ; DX:AX = dividendo
div bx ; ax=quoziente, dx=resto
add dl,30h
push dx ; salva il digit sullo stack
inc ecx ; incrementa contatore cifre
cmp ax,0
jne .loop1
mov eax,ecx ; salva numero digits
.loop2: ;recupera i digit dallo stack in ordine inverso (almeno 1)
pop dx
mov [esi],dl
inc esi
loop .loop2
mov ecx,eax ; return ECX
pop esi
pop edx
pop ebx
pop eax
ret
; FUNCTION: printasciiz
; stampa la stringa ASCIIZ in ingresso. La stringa è terminata da un NULL byte
; Parametri:
; EDX = indirizzo della stringa ASCIIZ
; Return:
; none
;
printasciiz:
push eax
push ecx
push edx
mov al,0
call strlen ; ecx=length
mov eax,ecx ; scambia ecx ed edx
mov ecx,edx ; indirizzo buffer in ecx
mov edx,eax ; length in edx
call write
pop edx
pop ecx
pop eax
ret
; FUNCTION: strlen
; calcola la lunghezza della stringa terminata dal char AL
; Parametri:
; AL = carattere terminatore
; EDX = indirizzo della stringa
; Return:
; ECX = lunghezza stringa
strlen:
push eax
push edx
push esi
mov esi,edx ; EDX=start string
.loop1:
mov ah,[esi]
cmp ah,al
je .end
inc esi
jmp .loop1
.end:
mov ecx,esi ; ECX=end string
sub ecx,edx ; sottrae dalla fine del buffer l'inizio
pop esi
pop edx
pop eax
ret
; FUNCTION: read
; legge un buffer da standard input
; Parametri:
; ECX = indirizzo del buffer
; EDX = lunghezza del buffer
;
read:
push eax
push ebx
mov eax, 03h ; read()
mov ebx, 00h ; stdin
int 80h
pop ebx
pop eax
ret
; FUNCTION: write
; scrive un buffer su standard input
; Parametri:
; ECX = indirizzo del buffer
; EDX = lunghezza del buffer
;
write:
push eax
push ebx
mov eax, 04h ; write()
mov ebx, 01h ; stdout
int 80h
pop ebx
pop eax
ret
OyBBc3NlbWJsYXRvcmUgTkFTTSAyLjA3CjsgY2FsY29sYSBpbCBudW1lcm8gZGkgY2lmcmUgZGVjaW1hbGkgJzInIHByZXNlbnRpIHRyYSBkdWUgbnVtZXJpIEEgZSBCCjsgY29tcHJlc2kgZ2xpIGVzdHJlbWkuIHN0YW1wYSBhbmNoZSBsYSBzZXF1ZW56YSBkZWkgbnVtZXJpLgo7IGVzZW1waW8gdHJhIGkgbnVtZXJpIDIwMDEgZSAyMDAxMiBjaSBzb25vIDE0IGNpZnJlICcyJwo7IHVzYSByZWdpc3RyaSBhIDE2IGJpdHMKOwo7IDIwMDEgMjAwMiAyMDAzIDIwMDQgMjAwNSAyMDA2IDIwMDcgMjAwOCAyMDA5IDIwMTAgMjAxMSAyMDEyCjsKCiAgICAgICAgZ2xvYmFsIF9zdGFydAogCnNlY3Rpb24gLmRhdGEKICAgICAgICBidWZmZXIgIHJlc2IgMTYKCW51bV9hCWR3IDIwMDEKCW51bV9iCWR3IDIwMTIKIApzZWN0aW9uIC50ZXh0CiAKX3N0YXJ0OgoJbW92CXNpLFtudW1fYV0JOyBtZXR0ZSBudW1lcm8gaW5pemlhbGUgaW4gU0kKCW1vdglkaSxbbnVtX2JdCTsgbWV0dGUgaWwgbnVtZXJvIGZpbmFsZSBpbiBESQoJbW92CWN4LDAJCTsgdXNvIENYIGNvbWUgY29udGF0b3JlIGRlbGxlIGNpZnJlICcyJwpsb29wMToKCW1vdglheCxzaQoJY2FsbAlwcmludF9heAk7IHN0YW1wbyBpbCBudW1lcm8gaW4gQVgKbG9vcDI6Cgl4b3IJZHgsZHgKCW1vdglieCwxMAoJZGl2CWJ4CgljbXAJZHgsMgoJam5lCW5vdF9kdWUKCWluYwljeApub3RfZHVlOgoJY21wCWF4LDAKCWpuZQlsb29wMgoJaW5jCXNpCgljbXAJc2ksZGkKCWpiZQlsb29wMQkKCgk7IG9yYSBpbiBDWCBobyBpbCBudW1lcm8gZGkgJzInIGUgbG8gc3RhbXBvCgltb3YJYXgsY3gKCWNhbGwJcHJpbnRfYXgKIApleGl0OgogICAgICAgIG1vdiAgICAgICAgICAgICBlYXgsIDAxaCAgICAgICAgICAgICAgICA7IGV4aXQoKQogICAgICAgIHhvciAgICAgICAgICAgICBlYngsIGVieCAgICAgICAgICAgICAgICA7IGVycm5vCiAgICAgICAgaW50ICAgICAgICAgICAgIDgwaAogCgoKcHJpbnRfYXgKCXB1c2gJZWF4CglwdXNoCWVjeAoJcHVzaAllZHgKCW1vdgllZHgsYnVmZmVyCgljYWxsCWJpbjJkZWMxNgoJbW92CWJ5dGUgW2J1ZmZlcitlY3hdLDBhaAk7IGFnZ2l1bmdlIG5ldy1saW5lCgltb3YJYnl0ZSBbYnVmZmVyK2VjeCsxXSwwCTsgbWFrZSBBU0NJSVoKCWNhbGwJcHJpbnRhc2NpaXoKCXBvcAllZHgKCXBvcAllY3gKCXBvcAllYXgKCXJldAoKCgoKCjsgRlVOQ1RJT046IGJpbjJkZWMxNgo7IGNvbnZlcnRlIHVuIG51bWVybyBiaW5hcmlvIGEgMTYgYml0IGluIHVuYSBzdHJpbmdhIEFTQ0lJIGRlY2ltYWxlCjsgUGFyYW1ldHJpOgo7CUFYICA9IG51bWVybyBkYSBzdGFtcGFyZQo7CUVEWCA9IGluZGlyaXp6byBkZWwgYnVmZmVyIEFTQ0lJICg1IGNpZnJlKQo7IFJldHVybjoKOwlFQ1ggPSBsdW5naGV6emEgZGVsbGEgc3RyaW5hZwpiaW4yZGVjMTY6CiAgICAgICAgcHVzaCAgICBlYXgKICAgICAgICBwdXNoICAgIGVieAogICAgICAgIHB1c2ggICAgZWR4CiAgICAgICAgcHVzaCAgICBlc2kKICAgICAgICBtb3YgICAgIGVzaSxlZHgKICAgICAgICBtb3YgICAgIGVjeCwwICAgOyBjb250YXRvcmUgY2lmcmUgc2lnbmlmaWNhdGl2ZQogICAgICAgIG1vdiAgICAgYngsMTAgICA7IGRpdmlzb3JlCi5sb29wMQogICAgICAgIHhvciAgICAgZHgsZHgJOyBEWDpBWCA9IGRpdmlkZW5kbwogICAgICAgIGRpdiAgICAgYnggICAgICA7IGF4PXF1b3ppZW50ZSwgZHg9cmVzdG8KICAgICAgICBhZGQgICAgIGRsLDMwaAogICAgICAgIHB1c2ggICAgZHggICAgICA7IHNhbHZhIGlsIGRpZ2l0IHN1bGxvIHN0YWNrCiAgICAgICAgaW5jICAgICBlY3ggICAgIDsgaW5jcmVtZW50YSBjb250YXRvcmUgY2lmcmUKICAgICAgICBjbXAgICAgIGF4LDAKICAgICAgICBqbmUgICAgIC5sb29wMQoKICAgICAgICBtb3YgICAgIGVheCxlY3ggOyBzYWx2YSBudW1lcm8gZGlnaXRzCgoubG9vcDI6CQk7cmVjdXBlcmEgaSBkaWdpdCBkYWxsbyBzdGFjayBpbiBvcmRpbmUgaW52ZXJzbyAoYWxtZW5vIDEpCiAgICAgICAgcG9wICAgICBkeAogICAgICAgIG1vdiAgICAgW2VzaV0sZGwKICAgICAgICBpbmMgICAgIGVzaQogICAgICAgIGxvb3AgICAgLmxvb3AyCiAgICAgICAgbW92ICAgICBlY3gsZWF4IDsgcmV0dXJuIEVDWAogICAgICAgIHBvcCAgICAgZXNpCiAgICAgICAgcG9wICAgICBlZHgKICAgICAgICBwb3AgICAgIGVieAogICAgICAgIHBvcCAgICAgZWF4CiAgICAgICAgcmV0CgoKOyBGVU5DVElPTjogcHJpbnRhc2NpaXoKOyBzdGFtcGEgbGEgc3RyaW5nYSBBU0NJSVogaW4gaW5ncmVzc28uIExhIHN0cmluZ2Egw6ggdGVybWluYXRhIGRhIHVuIE5VTEwgYnl0ZQo7IFBhcmFtZXRyaToKOwlFRFggPSBpbmRpcml6em8gZGVsbGEgc3RyaW5nYSBBU0NJSVoKOyBSZXR1cm46CjsJbm9uZQo7CnByaW50YXNjaWl6OgoJcHVzaAllYXgKCXB1c2gJZWN4CglwdXNoCWVkeAoJbW92CWFsLDAKCWNhbGwJc3RybGVuCTsgZWN4PWxlbmd0aAoJbW92CWVheCxlY3gJOyBzY2FtYmlhIGVjeCBlZCBlZHgKCW1vdgllY3gsZWR4CTsgaW5kaXJpenpvIGJ1ZmZlciBpbiBlY3gKCW1vdgllZHgsZWF4CTsgbGVuZ3RoIGluIGVkeAoJY2FsbAl3cml0ZQoJcG9wCWVkeAoJcG9wCWVjeAoJcG9wCWVheAoJcmV0CgoKOyBGVU5DVElPTjogc3RybGVuCjsgY2FsY29sYSBsYSBsdW5naGV6emEgZGVsbGEgc3RyaW5nYSB0ZXJtaW5hdGEgZGFsIGNoYXIgQUwKOyBQYXJhbWV0cmk6CjsJQUwgID0gY2FyYXR0ZXJlIHRlcm1pbmF0b3JlCjsJRURYID0gaW5kaXJpenpvIGRlbGxhIHN0cmluZ2EKOyBSZXR1cm46CjsJRUNYID0gbHVuZ2hlenphIHN0cmluZ2EKc3RybGVuOgoJcHVzaAllYXgKCXB1c2gJZWR4CglwdXNoCWVzaQoJbW92CWVzaSxlZHgJOyBFRFg9c3RhcnQgc3RyaW5nCi5sb29wMToKCW1vdglhaCxbZXNpXQoJY21wCWFoLGFsCglqZQkuZW5kCglpbmMJZXNpCglqbXAJLmxvb3AxCi5lbmQ6Cgltb3YJZWN4LGVzaQkJOyBFQ1g9ZW5kIHN0cmluZwoJc3ViCWVjeCxlZHgJCTsgc290dHJhZSBkYWxsYSBmaW5lIGRlbCBidWZmZXIgbCdpbml6aW8KCXBvcAllc2kKCXBvcAllZHgKCXBvcAllYXgKCXJldAoKCjsgRlVOQ1RJT046IHJlYWQKOyBsZWdnZSB1biBidWZmZXIgZGEgc3RhbmRhcmQgaW5wdXQKOyBQYXJhbWV0cmk6CjsJRUNYID0gaW5kaXJpenpvIGRlbCBidWZmZXIKOwlFRFggPSBsdW5naGV6emEgZGVsIGJ1ZmZlcgo7CnJlYWQ6CglwdXNoCWVheAoJcHVzaAllYngKCW1vdgllYXgsIDAzaAkJOyByZWFkKCkKCW1vdgllYngsIDAwaAkJOyBzdGRpbgoJaW50CTgwaAoJcG9wCWVieAoJcG9wCWVheAoJcmV0Cgo7IEZVTkNUSU9OOiB3cml0ZQo7IHNjcml2ZSB1biBidWZmZXIgc3Ugc3RhbmRhcmQgaW5wdXQKOyBQYXJhbWV0cmk6CjsJRUNYID0gaW5kaXJpenpvIGRlbCBidWZmZXIKOwlFRFggPSBsdW5naGV6emEgZGVsIGJ1ZmZlcgo7CndyaXRlOgoJcHVzaAllYXgKCXB1c2gJZWJ4Cgltb3YJZWF4LCAwNGgJCTsgd3JpdGUoKQoJbW92CWVieCwgMDFoCQk7IHN0ZG91dAoJaW50CTgwaAoJcG9wCWVieAoJcG9wCWVheAoJcmV0Cg==