2

I am writing some code that allows me to sum a table and then display its result using assembler language. Here is what I've come up with so far:

data segment 
  tab      db 9 dup(3 5 8 4 7 1 6 7 0)
  resultat db ?
data ends

code segment 
  xor di, di
  mov cx, 9
Prog: 
  mov al, tab[di]
  add ax, al
  inc di
loop prog
  mov resultat ,ax
  mov ah, 09h
  int 21h
end code
zx485
  • 28,498
  • 28
  • 50
  • 59
  • What assembler do you use? MASM, TASM, FASM, NASM...? – zx485 Nov 23 '16 at 19:56
  • Ela, your result is binary in `ax`, you have to convert it to string to display it. If you display `ax` you will see weird chars on screen. – Jose Manuel Abarca Rodríguez Nov 23 '16 at 19:59
  • am using emu 8086 –  Nov 23 '16 at 20:00
  • 1
    One of your code's problems is that you use the same register(`AX`=AH:AL) for two purposes: loading the current byte(`AL`) and accumulate the result in `AX`. – zx485 Nov 23 '16 at 20:00
  • yeah i don't know what to use to convert it –  Nov 23 '16 at 20:01
  • 2
    `add ax, al` is off, since you never initialised `ax` anyway. Is this supposed to double `al` since it is the l.s. part of `ax`? And then, you store `ax` (2 bytes) in `resultat` which has only 1 byte of memory allocated. – Weather Vane Nov 23 '16 at 20:39
  • 1
    Does this `db 9 dup(3 5 8 4 7 1 6 7 0)` really compile in emu8086? And does it produce 9 arrays of 9 bytes? That's ridiculous. For OP: the correct way is `db 3, 5, 8, 4, 7, 1, 6, 7, 0` to define 9 bytes. you don't want to 9 times duplicate (`DUP`) something what shouldn't even compile as single value. Use the `dup` to repeat single value several times. – Ped7g Nov 24 '16 at 11:08

3 Answers3

4

I made some changes in your code and stole proc number2string from another answer (full of comments to help you understand) :

data segment 
tab db 3,5,8,4,7,1,6,7,0 ;ARRAY OF NUMBERS.
resultat db '     $'  ;STRING WITH 5 CHARS.
data ends
code segment 
mov ax,@data    ;INITIALIZE
mov ds,ax       ;DATA SEGMENT.

xor di,di 
mov cx,9
xor ax,ax       ;CLEAR THE SUM ACCUMULATOR.
Prog:
add al,tab[di]
inc di
loop prog     

call number2string ;CONVERT AX TO STRING IN RESULTANT.

lea dx,resultat
mov ah,09h
int 21h

mov ax, 4c00h  
int 21h        ;TERMINATE PROGRAM.

;------------------------------------------
;NUMBER TO CONVERT MUST ENTER IN AX.
;ALGORITHM : EXTRACT DIGITS ONE BY ONE, STORE
;THEM IN STACK, THEN EXTRACT THEM IN REVERSE
;ORDER TO CONSTRUCT STRING.
;THE STRING IS STORED IN VARIABLE "RESULTAT".

proc number2string
  mov  bx, 10 ;DIGITS ARE EXTRACTED DIVIDING BY 10.
  mov  cx, 0 ;COUNTER FOR EXTRACTED DIGITS.
cycle1:       
  mov  dx, 0 ;NECESSARY TO DIVIDE BY BX.
  div  bx ;DX:AX / 10 = AX:QUOTIENT DX:REMAINDER.
  push dx ;PRESERVE DIGIT EXTRACTED FOR LATER.
  inc  cx ;INCREASE COUNTER FOR EVERY DIGIT EXTRACTED.
  cmp  ax, 0  ;IF NUMBER IS
  jne  cycle1 ;NOT ZERO, LOOP. 
;NOW RETRIEVE PUSHED DIGITS.
  lea  si, resultat
cycle2:  
  pop  dx        
  add  dl, 48 ;CONVERT DIGIT TO CHARACTER.
  mov  [si], dl
  inc  si
  loop cycle2  

  ret
endp  
;------------------------------------------

end code

The proc number2string converts to string any number in ax and stores the result in variable resultat (as it is defined in the data segment).

2

Adding a sequence of BYTEs can be done this way:

code segment 
  xor ax, ax       ; clear AX
  xor dx, dx       ; accumulator for result value
  lea si, tab      ; SI = address of TAB
  mov cx, 9        ; LEN of TAB in BYTEs
Prog: 
  lodsb            ; AL = BYTE PTR [SI] and increment SI
  add dx, ax       ; add 0:AL to DX
loop prog          ; decrements CX and jumps if not 0
  mov resultat, dx ; mov DX=accumulator to variable
  ; PROBLEM    !!!
  mov ah, 09h      ; !!! prints string and not a number !!!
  int 21h
  ; PROBLEM END!!!
  mov ah, 4Ch      ; exit program
  int 21h          
end code

This code adds CX=9 BYTE values in DX. The problem is that your "print" function does not work, because function AH=09h of INT 21h prints a string in DS:DX and not a number:

Int 21/AH=09h - DOS 1+ - WRITE STRING TO STANDARD OUTPUT
---
AH = 09h
DS:DX -> '$'-terminated string
---
Return:
AL = 24h (the '$' terminating the string, despite official docs which states that nothing is returned) (at least DOS 2.1-7.0 and
NWDOS)

So to print the number in DX you'd have to convert it to a string first.

zx485
  • 28,498
  • 28
  • 50
  • 59
  • how can i convert it to a string –  Nov 23 '16 at 20:48
  • 2
    There are already several SO answers covering that topic: [this](http://stackoverflow.com/a/40505492/1305969), [this](http://stackoverflow.com/a/39577676/1305969) and [this](http://stackoverflow.com/a/32102489/1305969). I hope this empowers you to solve this problem. – zx485 Nov 23 '16 at 21:05
-2
[bits 16]
[org 0x100]

jmp _start

_start:
    mov cl, 0
    mov ah, 0x0e

_loop:
    cmp cl, 10
    je _end

    mov al, byte cl
    or al, 30h ;Convert number to char
    int 0x10

    ;Print a space
    mov al, 0x20
    int 0x10

    inc cl
    jmp _loop

_end:
    mov ax, 0x4c
    int 0x21
Adam
  • 33
  • 4
  • Welcome to SO! You should always explain your code you post – rbr94 Nov 23 '16 at 20:37
  • 1
    This answer appears to print the digits from 0 to 9, and isn't summing an array at all. Even if it did work, there are no comments explaining why how the code answers the question. SO is not a coding service; the point of an answer is the explanation, not just working code (which this answer is lacking). – Peter Cordes Nov 23 '16 at 22:34