-1

I've a problem in assembly language that I want to make loop for sum element of an array.
Suppose an array contains 10,20,30,40,50,60,70,80,90,100 I have to sum all elements of the array by loop... How can I do this?


I'm trying this:

.MODEL SMALL
.STACK 100H
.DATA
W   DW 10,20,30,40,50,60,70,80,90,100
.CODE 
MAIN PROC
MOV AX, @data
MOV DS, AX

XOR AX, AX
XOR BX, BX
MOV CX, 10

ADDNOS:
ADD AX, W [BX]
ADD BX, 2
LOOP ADDNOS


;this for display
MOV DX, AX
MOV AH,2
INT 21H

MOV AH, 4CH
INT 21H
MAIN ENDP
END MAIN 


but something wrong in display that print from ascii (&).

Bsh
  • 21
  • 1
  • 6
  • May I suggest you to simply retry from scratch? I can't see a single line that it's worth keeping. Any useful answer can only be a complete solution to your homework –  Jul 02 '15 at 15:14

2 Answers2

1

EDIT: Updated answer since the code in the question has been changed:

INT 21h / AH=2 prints a single character (note that the integer 1 and the character '1' are different values).
The sum of the elements in your array is 550, which requires 3 characters to print. The way to solve that is to write a routine that converts the value 550 to the string "550", and then use INT 21h / AH=9 to print that string. How you'd go about doing that has been asked several times before on StackOverflow; see e.g. this question and the answers to it.


This is my answer for the original question

For future questions, note that "but something wrong" is a terrible problem description. You should explain precisely in what way the code isn't behaving the way you intended.

That said, there are a number of problems with your code:

Here you're initializing CX to the first value in x. Actually, since the elements in x are bytes (because you used DB) and CX is a word (two bytes) you'll get CX = 301h (which is 769 in decimal):

MOV CX, x

Here you're simply moving the first element of x into BX over and over, instead of doing an addition. And again, x contains bytes while BX is a word register.

top:    MOV BX, [x]

The loop instruction decrements CX by 1 and jumps to the given label if CX != 0. By incrementing CX before the loop you're creating an infinite loop. Also, the CMP is useless (and I'm not sure why you're comparing against 7 since x only has 5 elements):

INC CX
CMP CX, 7
loop top

This will only work for values in the range 0-9. If the sum is >=10 it will require multiple characters. See e.g. this answer for an example of how to convert a multi-digit number to a string that can be printed. Also, you're writing a word-sized register to a byte variable:

ADD BX, '0'
MOV [sum], BX

Here I'm a bit lost at what you're trying to do. If you wanted to write a single character to STDOUT you should use INT 21h / AH = 2 / DL = character. Note that MOV AX,4 sets AH=0 and AL=4. Also, you should end your program with INT 21h / AX = 4C00h:

display_:
    MOV DX,1
    MOV CX, sum
    MOV BX, 1
    MOV AX,4
    INT 21h
    MOV AX, 1
    INT 21h
Community
  • 1
  • 1
Michael
  • 57,169
  • 9
  • 80
  • 125
  • Seeing `MOV [sum], BX` in the code I suspect that `MOV CX, x` rather means putting the address of __x__ in CX. – Fifoernik Jul 02 '15 at 10:31
  • That may have been what the OP intended. But it's not what it actually means in the x86 assembly dialect used in the OP's code. – Michael Jul 02 '15 at 10:34
  • How to convert (value to string!)? I do this, `AP_: MOV DX,0 DIV BX ADD DX, 48 DEC SI MOV [SI], DL CMP AX,0 JZ EXTT JMP AP_ EXTT: MOV AH,9 MOV DX,SI INT 21H RET` but the program doesn't work – Bsh Jul 02 '15 at 20:46
-1

I suspect that there is an error in the code following the top label.

You do MOV BX, [x] but I think there you should sum the item pointed by CX with what currently is in BX (that seems to store the sum). So substitute the move instruction with:

ADD BX, [CX]
mziccard
  • 2,158
  • 9
  • 17
  • 2
    `[CX]` is not a valid effective address. And `CX` is not pointing to `x` (that would require the `OFFSET` operator in MASM/TASM syntax, which this code appears to be written in). – Michael Jul 02 '15 at 08:24