问题
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
回答1:
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.
回答3:
[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
来源:https://stackoverflow.com/questions/40772974/displaying-the-sum-of-a-table-using-assembler-8086