Well... you've got several issues here... Most important, perhaps, is that we can't get "numbers" from the keyboard, we get "characters"... specifically the ascii codes for the characters - the ascii code for '0' is 30h (48 decimal), the ascii code for '9' is 39h. Ascii codes outside of that range do not represent "decimal digits" (what will you do if the pesky user enters one?). There is no character '10'! So you're going to have to read two characters, say '1' and '0', and figure out that they represent the number 10 (0Ah). That's what you want to put in your "list".
When you get to the end, you've got an average, say 15. There's no character '15' that we can print, we're going to have to print a '1' and then a '5'.
These "ascii-to-integer" and "integer-to-ascii" conversions are conveniently done as subroutines (no sense repeating the code every time you need to do it!). If you want to use the C library, "scanf" and "printf" will do nicely. So far, you've used only the int 80h interface - it's a shame to drag in the whole C library just to convert a few two-digit numbers! (but it's sitting there in memory, just waiting to be used, and is fairly easy, if you want to do it that way).
I happen to think that it's a pretty good "exercise" for a beginner, figuring out how to put together a sequence of simple-minded CPU instructions to "do something useful". Other people think it's a "waste of time", making a beginner do that. Often there's a "read_int" and "write_int" routine included in your "course materials" that you can use. You can find examples to "go by" (or "borrow") fairly easily. We can discuss it further, if you want to go that route. You'll need to write, or learn to use, such a routine, in any case!
segment .data
msg db 'Enter a digit from 10 to 99: #'
len equ $-msg
You can't very well enter a number between 10 and 99 with just "a" digit. This is just a nit-pick, of course. You can say anything you like. It is traditional to be "user friendly" but you can start off with, "Listen up, Earthling!" if you want. I'd just refer to it as "a number"... if you say "decimal number" (even though that's what you want), they're liable to give you something with a decimal point in it (which you don't want!). Maybe even say "whole number"... gotta keep it simple for users - they get confused easily.
segment .bss
buffer: resb 1
This isn't big enough! You'll want space for two bytes/characters, at least, plus perhaps another for the CR that will terminate input, or perhaps a terminating zero (if you're going to use C, you'll want a terminating zero... which the sys_read call does not provide - you'll have to add it yourself). I'd go with "resb 3", I think.
list: resb 10
segment .text
global _start
_start:
mov esi, 0
mov ecx, 10
read: mov eax, 4
mov ebx, 1
mov edi, ecx
Okay, if you're going to do it that way. You might want to move this out of the middle of the sys_write setup, just for clarity...
mov ecx, msg
mov edx, len
int 0x80
mov eax, 3
mov ebx, 0
mov ecx, buffer
edx, the "max length to read" is still the length of your prompt, from above. You probably don't want to let the user enter that many characters - you only asked for two! (might want to allow three?)
int 0x80
mov [list+esi], buffer <----- Error
Nasm demands a "size" here. Just "buffer", without "[]", refers to the address of the buffer, a dword. But your "list" is just bytes. Doesn't matter, basically you don't want to do it at all. At this point, you need that "ascii to number" routine. That will probably return the number in al (or eax - but we only need al). If you do:
mov [list + esi], al
... Nasm won't have to ask the size - the al register, being a byte, determines the size.
add edi, 1
I think you want esi, here (to get to the next position in "list"). If you do this (edi), ecx will be incremented, too, and your loop will never end!
mov ecx, edi
loop read
The "loop" instruction uses ecx. The system calls want to use ecx, too. You can save and restore ecx as your loop counter by moving it into and out of edi (as you've done... almost), or by pushing and popping it. But you can do a loop without the "loop" instruction. S'pose you'd loaded edi with 10 (your loop count) up top where you used ecx. Then you could:
dec edi ; or sub edi, 1
jnz read
... does the same thing ("loop" is shorter, but slower), without depending on ecx. Either should work...
mov eax, 4
mov ecx, 1
ebx?
mov ecx, list
mov edx, 20
20? Okay, ten numbers at two bytes each... but "list" is only ten bytes! This isn't going to do what you want, anyway - you need to use that "number to ascii" routine, and print the resulting string...
int 0x80
exit: mov eax, 1
int 0x80
It's "polite" to return some "meaningful" value (in ebx, but only bl "counts"). Zero usually indicates "no error". But you're not using it anyway. Good job remembering to exit cleanly back to the shell!
Think about what you want to do for those "ascii to integer" and "integer to ascii" routines. Easiest if you've been "given" some routines to use, but they aren't too hard to write - give it a shot. Or libc is there for us to use... We'll talk again...
Best,
Frank