Montaje 8086 | Suma de una matriz, impresión de números de varios dígitos

He escrito un código bastante simple en asm x8086 y estoy enfrentando un error. Si alguien pudiera ayudarme con una breve explicación, lo agradecería mucho.

IDEAL MODEL small STACK 100h DATASEG ; -------------------------- array db 10h, 04h, 04h, 04h, 04h, 04h, 04h, 04h, 04h, 04h sum db 0 ; -------------------------- CODESEG start: mov ax, @data mov ds, ax ; -------------------------- xor cx, cx mov al, 0 mov bx, offset array StartLoop: cmp cx, 10 jge EndLoop add al, [bx] add [sum],al inc cx inc bx jmp StartLoop EndLoop: mov ah, 09h int 21h ; -------------------------- exit: mov ax, 4c00h int 21h END start 

Con la corrección para que el add sea ​​reemplazado por mov como se indica en su comentario ( Note que la línea: add al, [bx] es en realidad mov al, [bx] ) ¡simplemente está la llamada de función en la etiqueta EndLoop que está mal!

Desea mostrar la sum y está utilizando la función de impresión de DOS. Esta función 09h espera un puntero en DS: DX que no está proporcionando!
Incluso si lo hiciera, igual tendría que convertir el número de sum en su representación de texto.

Una solución rápida aquí sería contentarte y solo mostrar el resultado en forma de un único carácter ASCII. La sum codificada es 52 y por lo tanto es un personaje que se puede visualizar:

 EndLoop: mov dl, [sum] mov ah, 02h ;Single character output int 21h ; -------------------------- exit: mov ax, 4c00h int 21h 

Un paso más y podemos mostrar “52”:

 mov al,[sum] mov ah,0 mov dl,10 div dl ---> AL=5 AH=2 add ax,3030h ---> AL="5" AH="2" mov dh,ah ;preserve AH mov dl,al mov ah,02h int 21h mov dl,dh ;restre int 21h 

No veo ningún error en absoluto, el código sumrá la matriz, mostrará algunas sh * t al azar y saldrá.

¿Probablemente quiera mostrar el resultado de la sum?

int 21h, ah=9 mostrará cadena terminada '$' de la memoria apuntada por dx .

Entonces necesita dos cosas, convierta el número en [sum] en cadena terminada por '$' al final, y luego establezca dx en la cadena convertida antes de esa int 21h .

Puede intentar extraer el procedimiento number2string desde aquí: https://stackoverflow.com/a/29826819/4271923

Personalmente lo cambiaría para tomar la dirección del buffer de destino en si como otro argumento de llamada (es decir, simplemente eliminar el mov si,offset str del cuerpo del procedimiento). Me gusta esto:

 PROC number2string ; arguments: ; ax = unsigned number to convert ; si = pointer to string buffer (must have 6+ bytes) ; modifies: ax, bx, cx, dx, si mov bx, 10 ; radix 10 (decimal number formatting) xor cx, cx ; counter of extracted digits set to zero number2string_divide_by_radix: ; calculate single digit xor dx, dx ; dx = 0 (dx:ax = 32b number to divide) div bx ; divide dx:ax by radix, remainder will be in dx ; store the remainder in stack push dx inc cx ; loop till number is zero test ax, ax jnz number2string_divide_by_radix ; now convert stored digits in stack into string number2string_write_string: pop dx add dl, '0' ; convert 0-9 value into '0'-'9' ASCII character encoding ; store character at end of string mov [si], dl inc si ; loop till all digits are written dec cx jnz number2string_write_string ; store '$' terminator at end mov BYTE PTR [si],'$' ret ENDP 

Luego, para invocar esto en su EndLoop , debe agregar al segmento de datos numberStr DB 8 DUP (0) para tener un búfer de memoria asignado para la cadena y agregarlo al código:

  ; load sum as 16b unsigned value into ax xor ax,ax ; ax = 0 mov al,[sum] ; ax = sum (16b zero extended) ; convert it to string mov si,OFFSET numberStr call number2string ; display the '$' terminated string mov dx,OFFSET numberStr mov ah,9 int 21h ; ... exit ...