Well....
mov al, i
What does this do? It mov's (or attempts to) the address of i into al. The address of i is a 32-bit quantity, and won't fit into an 8-bit register, thus the problem. What you actually want to do here is mov the "[contents]" of i into al:
mov al, [i]
That change alone will shut Nasm/Yasm up, and your program will assemble and link without complaint, but it still won't work as intended. You do essentially the same thing earlier...
section .bss
mychar resb 1
section .data
cr db 0x0a
msg db 'string<cr> : '
len equ $ - msg
i db 0
msg2 db 'Too Long! ' ; sequence of ASCII characters
len2 equ $ - msg2 ; number of characters
section .text
global _start
_start:
mov edx, len
mov ecx, msg
mov ebx, 1
mov eax, 4
int 0x80
jmp reading
counter:
mov ecx, i
add ecx, 1
Again, you want "[contents]" of memory, not the address. This time, it's going into a 32-bit register, so ld doesn't whine, but it isn't really what you want to do. "[ i ]" (spaces required to keep the forum software from switching us to italics!) is only a byte long, so you're mov'ing the first couple (three) characters of "Too long" into ecx. This doesn't actually do any harm, but it isn't "right". You probably want to use an 8-bit register here - cl will do...
Having incremented the count in cl (or ecx), what do you do with it? Nuthin'!!! You probably want to store the new value back into "[ i ]", eh? If you do:
mov [i], ecx
... it will clobber the first bytes of "Too long". Since adding 1 won't change these upper bytes (until you get to 255 in [ i ], which you don't, you won't see any problem, but it's still not "right". Use an 8-bit register... or... we can manipulate the value in memory without mov'ing it into a register and back. If you do:
add [i], 1
... since there's no 8- or 32-bit register involved, Nasm doesn't know "how big of a 1" to add, it'll complain about "operation size not specified". Some assemblers (noteably Masm) do remember that you said "i" was "db" and will do the right thing, but Nasm (and, I think, Yasm) has amnesia and needs to be told:
add byte [i], 1
;or
add [i], byte 1
Either way should work. If you're more comfortable with a register, use that. There are cases where we need to use a register... if we wanted to move [ i ] into [j], say...
mov byte [j], [i] ; <- RONG!
Sorry, no such instruction! We need to use a register:
mov cl, [i]
mov [j], cl
That doesn't apply to your code, but I though I'd mention it, since we're on the subject. Back to your code...
reading:
mov edx, 1
mov ecx, mychar
mov ebx, 0
mov eax, 3
int 0x80
mov al, [mychar]
cmp al, [cr]
jne counter ; jump if mychar != cr
mov al, i ; <- here's the "truncate" error
cmp al, 10
jg toolong
jmp finish
toolong:
;print out
mov edx, len2
mov ecx, msg2
mov ebx, 1
mov eax, 4
int 0x80
finish:
mov eax, 1 ; exit()
int 0x80
I think with those minor changes, your code will work as intended. Good job!
Best,
Frank