Actually, I think the very first error is only reserving a single byte for "cont", and then putting a dword in it. That isn't doing any harm right now, but it will if you put another variable after it.
section .data
stringa db "Hello", 0ah, 0
section .bss
cont resb 1 ; <- needs to be more!
section .text
global _start
_start:
call ini
call conta
call fine
ini:
mov eax, 0
mov ecx, 0
mov esi, 0
ret
conta:
cmp eax, '0ah' ;
je stampa
movzx eax, byte[stringa+ecx]
inc ecx
cmp eax, 5Bh ; <- '['
jl incrementa
jg conta
ret
incrementa:
inc esi
add esi, 30h
mov [cont], esi
jmp conta
; this works the first time, but what happens
; when you encounter a second (or more) uppercase
; character? esi is already 31h - we bump it up to 32h
; and then add another 30h! not going to be the
; number you want...
stampa:
mov eax,4
mov ebx,1
mov ecx, cont
mov edx, 1
int 80h
ret
fine:
mov eax, 1
mov ebx, 0
int 80h
I think Gammac has nailed the cause of your segfault. The comparison with '0ah' is never going to succeed, so you keep incrementing ecx until you run off into memory that you don't "own". Go boom! You've probably already got that fixed.
I've noted a problem with counting the second (or more) uppercase character. Could fix that by subtracting 30h from esi again after putting it in "[cont]". There's another problem awaiting when you get to 10. That's the whole "how do I display a number?" question. We've covered that, but we can go over it again. Get it working for single digits first...
I absolutely agree that commenting your code will help. There's a guy over on Stack Overflow (Brendan?) who claims there are only two possible errors in assembly code. Either the comments don't describe a correct algorithm, or the code doesn't do what the comments say. An interesting way to look at it...
Well, I see you guys have gotten way ahead of me while I've been typing. Go for it!
Best,
Frank