fork download
  1. ; Assemblatore NASM 2.07
  2. ; calcola il numero di cifre decimali '2' presenti tra due numeri A e B
  3. ; compresi gli estremi. stampa anche la sequenza dei numeri.
  4. ; esempio tra i numeri 2001 e 20012 ci sono 14 cifre '2'
  5. ; usa registri a 16 bits
  6. ;
  7. ; 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012
  8. ;
  9.  
  10. global _start
  11.  
  12. section .data
  13. buffer resb 16
  14. num_a dw 2001
  15. num_b dw 2012
  16.  
  17. section .text
  18.  
  19. _start:
  20. mov si,[num_a] ; mette numero iniziale in SI
  21. mov di,[num_b] ; mette il numero finale in DI
  22. mov cx,0 ; uso CX come contatore delle cifre '2'
  23. loop1:
  24. mov ax,si
  25. call print_ax ; stampo il numero in AX
  26. loop2:
  27. xor dx,dx
  28. mov bx,10
  29. div bx
  30. cmp dx,2
  31. jne not_due
  32. inc cx
  33. not_due:
  34. cmp ax,0
  35. jne loop2
  36. inc si
  37. cmp si,di
  38. jbe loop1
  39.  
  40. ; ora in CX ho il numero di '2' e lo stampo
  41. mov ax,cx
  42. call print_ax
  43.  
  44. exit:
  45. mov eax, 01h ; exit()
  46. xor ebx, ebx ; errno
  47. int 80h
  48.  
  49.  
  50.  
  51. print_ax
  52. push eax
  53. push ecx
  54. push edx
  55. mov edx,buffer
  56. call bin2dec16
  57. mov byte [buffer+ecx],0ah ; aggiunge new-line
  58. mov byte [buffer+ecx+1],0 ; make ASCIIZ
  59. call printasciiz
  60. pop edx
  61. pop ecx
  62. pop eax
  63. ret
  64.  
  65.  
  66.  
  67.  
  68.  
  69. ; FUNCTION: bin2dec16
  70. ; converte un numero binario a 16 bit in una stringa ASCII decimale
  71. ; Parametri:
  72. ; AX = numero da stampare
  73. ; EDX = indirizzo del buffer ASCII (5 cifre)
  74. ; Return:
  75. ; ECX = lunghezza della strinag
  76. bin2dec16:
  77. push eax
  78. push ebx
  79. push edx
  80. push esi
  81. mov esi,edx
  82. mov ecx,0 ; contatore cifre significative
  83. mov bx,10 ; divisore
  84. .loop1
  85. xor dx,dx ; DX:AX = dividendo
  86. div bx ; ax=quoziente, dx=resto
  87. add dl,30h
  88. push dx ; salva il digit sullo stack
  89. inc ecx ; incrementa contatore cifre
  90. cmp ax,0
  91. jne .loop1
  92.  
  93. mov eax,ecx ; salva numero digits
  94.  
  95. .loop2: ;recupera i digit dallo stack in ordine inverso (almeno 1)
  96. pop dx
  97. mov [esi],dl
  98. inc esi
  99. loop .loop2
  100. mov ecx,eax ; return ECX
  101. pop esi
  102. pop edx
  103. pop ebx
  104. pop eax
  105. ret
  106.  
  107.  
  108. ; FUNCTION: printasciiz
  109. ; stampa la stringa ASCIIZ in ingresso. La stringa è terminata da un NULL byte
  110. ; Parametri:
  111. ; EDX = indirizzo della stringa ASCIIZ
  112. ; Return:
  113. ; none
  114. ;
  115. printasciiz:
  116. push eax
  117. push ecx
  118. push edx
  119. mov al,0
  120. call strlen ; ecx=length
  121. mov eax,ecx ; scambia ecx ed edx
  122. mov ecx,edx ; indirizzo buffer in ecx
  123. mov edx,eax ; length in edx
  124. call write
  125. pop edx
  126. pop ecx
  127. pop eax
  128. ret
  129.  
  130.  
  131. ; FUNCTION: strlen
  132. ; calcola la lunghezza della stringa terminata dal char AL
  133. ; Parametri:
  134. ; AL = carattere terminatore
  135. ; EDX = indirizzo della stringa
  136. ; Return:
  137. ; ECX = lunghezza stringa
  138. strlen:
  139. push eax
  140. push edx
  141. push esi
  142. mov esi,edx ; EDX=start string
  143. .loop1:
  144. mov ah,[esi]
  145. cmp ah,al
  146. je .end
  147. inc esi
  148. jmp .loop1
  149. .end:
  150. mov ecx,esi ; ECX=end string
  151. sub ecx,edx ; sottrae dalla fine del buffer l'inizio
  152. pop esi
  153. pop edx
  154. pop eax
  155. ret
  156.  
  157.  
  158. ; FUNCTION: read
  159. ; legge un buffer da standard input
  160. ; Parametri:
  161. ; ECX = indirizzo del buffer
  162. ; EDX = lunghezza del buffer
  163. ;
  164. read:
  165. push eax
  166. push ebx
  167. mov eax, 03h ; read()
  168. mov ebx, 00h ; stdin
  169. int 80h
  170. pop ebx
  171. pop eax
  172. ret
  173.  
  174. ; FUNCTION: write
  175. ; scrive un buffer su standard input
  176. ; Parametri:
  177. ; ECX = indirizzo del buffer
  178. ; EDX = lunghezza del buffer
  179. ;
  180. write:
  181. push eax
  182. push ebx
  183. mov eax, 04h ; write()
  184. mov ebx, 01h ; stdout
  185. int 80h
  186. pop ebx
  187. pop eax
  188. ret
  189.  
Success #stdin #stdout 0.02s 144KB
stdin
Standard input is empty
stdout
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
14