I've been trying for a while to input the name (max 20 characters) and output it. If I try to output the name exactly after I input it everything is fine but if I try to output it near the end of the code (check arrows) it outputs nothing. While debuging using the word "train" as input I saw the array_name got the letter "t" at it's first position but in the line where I say "<~~~~array_name goes from "T" to 0 after this lane~~~~" it turns to 0 and I can't find why. Here is my code, I have arrows as comments in the spots that have to do with it. Everything works except this little one.
TITLE Expression calculator (Project_4_a.asm)
; This program ………
INCLUDE Irvine32.inc
table_size EQU 8d
name_size EQU 21d ;<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.data
array_number SWORD table_size DUP (?)
array_name WORD name_size DUP (?) ;<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
string0 BYTE "Enter your name <max 20 characters>:", 0
string1 BYTE "Enter a degree for lesson N.", 0
string2 BYTE ":", 0
string3 BYTE "Degree for lesson N.", 0
string4 BYTE "Average deegree <student:", 0
string5 BYTE ">= ", 0
counter BYTE 0d
counter2 BYTE 0d
average WORD 0d
.code
main PROC
mov EDX, OFFSET string0
CALL WriteString
mov EDX, OFFSET array_name ;<~~~~~~~~~~~~~Read~~~~~~~~~~~~~~~~~
mov ECX, name_size ;<~~~~~~~~~~~~~~~~~~~~~Read~~~~~~~~~~~~~~~~
call ReadString ;<~~~~~~~~~~~~~~~~~~~~~~~~Read~~~~~~~~~~~~~~
;If i put the 2 lines below it outputs the string correctly.
;mov EDX, OFFSET array_name
;CALL WriteString
call Crlf
mov ECX, table_size ; ECX=8
mov EDI, 0d
L1:
mov EBX, offset array_number ;
mov EDX, OFFSET string1 ; output
CALL WriteString ; output
ADD counter, 1d ; output
MOVZX EAX, counter ; output
CALL WriteDec ; output
mov EDX, OFFSET string2 ; output
CALL WriteString ; output
CALL ReadDec ; input
ADD EBX,EDI ;
ADD EDI, type array_number
MOV [EBX], EAX ; fill array <~~~~array_name goe from "T" to 0 after this lane~~~~
CALL Crlf
LOOP L1
mov ECX, table_size
mov AX, 0d
mov ESI, offset array_number
L2:
sub ECX, 1
ADD AX, [esi + ECX * TYPE array_number]
add ECX, 1
LOOP L2
SHR AX,3
MOV average, AX ;
MOV ECX, table_size
L3:
mov EDX, OFFSET string3 ; output
CALL WriteString ; output
MOV EAX, ECX ; output
CALL WriteDec ; output
mov EDX, OFFSET string2 ; output
CALL WriteString ; output
mov ESI, offset array_number
sub ECX,1
MOV BX, [esi + ECX * TYPE array_number]
add ECX,1
MOVZX EAX, BX
CALL WriteInt
CALL Crlf
LOOP L3
mov EDX, OFFSET string4 ; output
CALL WriteString ; output
mov EDX, OFFSET array_name ; output ;<~~~~~~~~~~~~~write~~~~~~~~~~~~~~~~~~~~~~
CALL WriteString ; output ;<~~~~~~~~~~~~~~~~~~~~~~~write~~~~~~~~~~~~~~
mov EDX, OFFSET string5 ; output
CALL WriteString ; output
MOVZX EAX, average ; output
CALL WriteDec ; output
CALL Crlf
exit
main ENDP
END main
Okay, I see this uses a library associated with a book that I don't have.
This is a tricky bug. The problem is that you declared array_number
as an array of 2-byte words. In the 8th iteration through the problematic loop, the EBX
register will have a value array_number + 14
. The instruction MOV [EBX], EAX
then executes the last time. This instruction moves 4 bytes. So it overwrites the 2 bytes beyond array_number
, which are the first two bytes of array_name
. Moreover, these are the high 2 bytes of whatever number you input, so unless you type an input bigger than 255, they will be 0 as you are observing.
I think you meant either to declare array_number
to be of type SDWORD
or else the MOV
instruction should be copying only 2 bytes, not 4.
Incidentally, your library is documented here. This is the info I needed to make sense of your program.