I have written the program for the above question,and i have a few
questions regarding the program, can some help me in answering my
questions.
My questions are:
1.actually iam adding each row elements and calculating their average.
2.and i have to display the persons name and his average on the same
line.
so can anyone tell me how do i display the average besides a person
name.
i am able to do for the first person i,e moving average into char1
which i have declared in the .DATA SEGMENT FOR FIRST MESSAGE.But how
do i display for each and every person.
3.and iam getting the following error when i am trying to execute the
program which i have written.can some one help me in debugging this
error.
the instruction at line 46 is MOV BX,18 is there anything wrong in
this instruction.
F:\SRIDOC~1\asm\masm611>masm student;
Microsoft (R) MASM Compatibility Driver
Copyright (C) Microsoft Corp 1993. All rights reserved.
Invoking: ML.EXE /I. /Zm /c student.asm
Microsoft (R) Macro Assembler Version 6.11
Copyright (C) Microsoft Corp 1981-1993. All rights reserved.
Assembling: student.asm
student.asm(46): error A2081: missing operand after unary operator
student.asm(100): fatal error A1008: unmatched macro nesting
F:\SRIDOC~1\asm\masm611>
The program which i have written for the above question is as follows:
;Program to print the name of each student and his/her
average(truncated to an integer)
;for the four students
TITLE PROGRAM : STUDENT RECORD
.MODEL SMALL
.STACK 100H
.DATA
MSG1 DB 'MARY ALLEN : $'
CHAR1 DB ?
MSG2 DB 'SCOTT BAYLIS : $'
CHAR2 DB ?
MSG DB 'GEORGE FRANK : $'
CHAR3 DB ?
MSG4 DB 'SAM WONG : $'
CHAR4 DB ?
FOUR DW 4
SCORES DW 67,45,98,33 ;MARY ALLEN
DW 70,56,87,44 ;SCOTT BAYLIS
DW 82,72,89,40 ;GEORGE FRANK
DW 78,76,92,60 ;SAM WONG
AVG DW 4 DUP (0)
.CODE
MAIN PROC
MOV AX,@DATA
MOV DS,AX ;initialize Ds
;i = 4
MOV BX,18 ;row index, initially row 4
REPEAT:
MOV CX,4 ;no. of rows
XOR SI,SI ;col index,initially 1
XOR AX,AX ;col_sum, initially 0
;sum scores in column j
For:
ADD AX,SCORES[BX+SI] ;row_sum = row_sum + score(BX = ROW, SI
= COL)
ADD BX,2 ;move pointer to the next element
LOOP FOR ;keep adding scores
;endfor
;compute average in column j
XOR DX,DX ;clear high part of dividend
DIV FOUR ;AX = average
MOV AVG[BX],AX ;store in array
MOV CHAR1,AVG[BX]
SUB BX,8 ;go to next row
;until i = 0
JNL REPEAT ;unless SI < 0
;print the first message
LEA DX,MSG1 ;get the first message
MOV AH,9 ;display string funtion
INT 21H ;display message and average
;dos exit
MOV AH,4CH
INT 21H
MAIN ENDP
END MAIN
Interesting assignment. The way the data is given (if each name really
were 12 bytes), you could write a fairly easy solution. But it wouldn't
be a very good program - too hard to alter if, say, we wanted to add a
5th test...
You've changed the way the data is arranged. That's not a bad idea, but
it isn't really what the assignment asks for...
> I have written the program for the above question,and i have a few
> questions regarding the program, can some help me in answering my
> questions.
>
> My questions are:
> 1.actually iam adding each row elements and calculating their average.
I'm not sure what you're actually adding, but you've got the right idea.
> 2.and i have to display the persons name and his average on the same
> line.
> so can anyone tell me how do i display the average besides a person
> name.
> i am able to do for the first person i,e moving average into char1
> which i have declared in the .DATA SEGMENT FOR FIRST MESSAGE.But how
> do i display for each and every person.
Well, from what I can see, everything will be on the same line. You just
need to print the name, probably print a space, print the average, and
print a carriage return, linefeed pair. Your actual problem is printing
the average... suppose the average comes out to 65... if you print that
to the screen, it'll come out as the letter 'A'! You need to print '6'
and '5'. Do you know how to do that?
> 3.and iam getting the following error when i am trying to execute the
> program which i have written.can some one help me in debugging this
> error.
>
> the instruction at line 46 is MOV BX,18 is there anything wrong in
> this instruction.
That instruction looks okay to me (I'm not sure why 18...). Could the
problem be on the next line? I suspect that "repeat" may be a "keyword"
to Masm (I'm Nasmist, so I'm not sure). That would account for strange
errors.
> F:\SRIDOC~1\asm\masm611>masm student;
> Microsoft (R) MASM Compatibility Driver
> Copyright (C) Microsoft Corp 1993. All rights reserved.
>
> Invoking: ML.EXE /I. /Zm /c student.asm
>
> Microsoft (R) Macro Assembler Version 6.11
> Copyright (C) Microsoft Corp 1981-1993. All rights reserved.
>
> Assembling: student.asm
> student.asm(46): error A2081: missing operand after unary operator
> student.asm(100): fatal error A1008: unmatched macro nesting
The "unmatched macro nesting" can come from not getting "endp" and "end"
right, but I think you've got that right... which furthers my suspicion
that "repeat" is the problem...
Why 18?
> REPEAT:
Try changing this to "do_some_more:", or something Masm *won't* be using...
> MOV CX,4 ;no. of rows
>
> XOR SI,SI ;col index,initially 1
Comment does not match code...
> XOR AX,AX ;col_sum, initially 0
>
> ;sum scores in column j
>
> For:
Might Masm be using "for", also?
> ADD AX,SCORES[BX+SI] ;row_sum = row_sum + score(BX = ROW, SI
> = COL)
>
> ADD BX,2 ;move pointer to the next element
>
> LOOP FOR ;keep adding scores
>
> ;endfor
>
> ;compute average in column j
>
> XOR DX,DX ;clear high part of dividend
>
> DIV FOUR ;AX = average
>
> MOV AVG[BX],AX ;store in array
This would seem to write beyond your array...
> MOV CHAR1,AVG[BX]
Now *this* looks like an invalid instruction to me. Maybe I'm confused
by the Masm syntax, but it looks like a memory-to-memory move, which you
can't do. Since the average is still in ax... well, just do "mov char1,
al", since char1 is a byte (but it won't display as an ascii number,
anyway...).
> SUB BX,8 ;go to next row
Lets see... you've just added bx, 2 four times... now you subtract 8...
I think you're back on the same row. Perhaps you intended to add
something to si here? You don't seem to actually do anything with si...
> ;until i = 0
>
> JNL REPEAT ;unless SI < 0
Comment does not match code...
> ;print the first message
>
> LEA DX,MSG1 ;get the first message
>
> MOV AH,9 ;display string funtion
>
> INT 21H ;display message and average
Well, this is only going to display to the '$'...
> ;dos exit
>
> MOV AH,4CH
>
> INT 21H
>
> MAIN ENDP
>
> END MAIN
I'd be tempted to put the data back the way it's "supposed" to be - 12
bytes of name, followed by 4 bytes of "scores". Then, rather than try to
display the name all at once with int 21h/9, I'd display it a character
at a time with int 21h/2 - 12 times. Or perhaps I'd use int 21h/40h -
the file-write function - with bx=1 for "stdout" and cx=12. Something
that writes a known length, rather than expecting a terminator.
The "scores" will individually fit in a byte, but adding 4 of them
together will probably overflow - I assume that's why you changed 'em to
word. You might cope with the problem like this:
xor ax, ax
for_each_score:
add al, data[index]
adc ah, 0
...
Only increment your index by 1, of course, it's only a byte array now.
That'll give you a word "sum" to divide by 4. Tempting to just shift to
do the divide, since it's 4 - but that's not very easily changed if we
had 5 tests. Better to divide by a memory location, as you've done -
call it "number_of_tests" or something, rather than "four", though...
Then you'd want to "convert" the average to an ascii string to print it,
probably print a carriage return, linefeed pair, and continue with the
next 12 bytes of "name", etc... Maybe do it "number_of_students" times,
rather than "4", to make that changeable, too...
I think that's how I'd approach it...
Best,
Frank
; AUTHOR emu8086
; DATE ?
; VERSION 1.00
; FILE ?.ASM
; 8086 Code Template
; Directive to make EXE output:
; #MAKE_EXE#
;Program to print the name of each student and his/her average(truncated to
an integer)
;for the four students
TITLE PROGRAM : STUDENT RECORD
.MODEL SMALL
.STACK 100H
.DATA
records:
MSG1 DB 'MARY ALLEN: ' ;---------all names 16 bytes long + result = 22
bytes total per record
char1 DB ?,?,?,?,?, '$' ;----------------------- moved the '$' terminator
to include the result--------
MSG2 DB 'SCOTT BAYLIS: '
CHAR2 DB ?,?,?,?,?, '$' ;----------------------- moved the '$' terminator
to include the result--------
MSG3 DB 'GEORGE FRANK: '
CHAR3 DB ?,?,?,?,?, '$' ;----------------------- moved the '$' terminator
to include the result--------
MSG4 DB 'SAM WONG: '
CHAR4 DB ?,?,?,?,?, '$' ;----------------------- moved the '$' terminator
to include the result--------
FOUR DW 4
TEN DW 10 ;----------------for bcd conversion---------
SCORES DW 67,45,98,33 ;MARY ALLEN
DW 70,56,87,44 ;SCOTT BAYLIS
DW 82,72,89,40 ;GEORGE FRANK
DW 78,76,92,60 ;SAM WONG
AVG DW 4 DUP (0)
.CODE
MAIN PROC
MOV AX,@DATA
MOV DS,AX ;initialize Ds
xor di,di ;-----------current avg
xor bx,bx ;-----------current row
average:
XOR SI,SI ;col index,initially 0
XOR AX,AX ;col_sum, initially 0
sum:
ADD AX,SCORES[BX+SI] ;row_sum = row_sum + score(BX = ROW, SI= COL)
ADD si, 2 ;move pointer to the next element
cmp si, 6
jbe sum
XOR DX,DX ;clear high part of dividend
DIV word ptr FOUR;AX = average
mov AVG[di],ax ;store in array
add BX,8 ;go to next row
add DI,2 ;next word in avg[]
cmp di,8 ;compare with double the row count to preserve one mul on store in
avg[di*2] array
Jb average
;--------convert average to bcd then to ascii (for printing)
;--------------------------
xor si,si
mov bx,16
toascii:
mov ax, avg[si]
XOR DX,DX
div word ptr ten ;divide last quotient by ten to get the decimal digit
mov [records+bx+4],dl
XOR DX,DX
div word ptr ten
mov [records+bx+3],dl
or word ptr [records+bx+3], 3030h ;two bcd to ascii
XOR DX,DX
div word ptr ten
mov [records+bx+2],dl
XOR DX,DX
div word ptr ten
mov [records+bx+1],dl
or word ptr [records+bx+1], 3030h
XOR DX,DX
div word ptr ten
mov [records+bx ],dl
or word ptr [records+bx ], 30h ;one bcd to ascii
add BX,22 ;go to next charX
add si,2 ;next word in avg[]
cmp si,8 ;compare with double the row count to preserve one mul on store in
avg[si*2] array
Jb toascii
;--------------------------