2016-11-09 3 views
4

Я написал довольно простой код в asm x8086, и я столкнулся с ошибкой. Если бы кто-нибудь мог помочь мне с кратким объяснением, я бы очень признателен.Ассамблея 8086 | Сумма массива, печать многозначных чисел

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 
+2

Обратите внимание, что строка: добавить al, [bx] на самом деле mov al, [bx] –

+0

Я думаю, что краткое объяснение здесь: http://stackoverflow.com/help/how-to-ask (На данный момент непонятно, что вы просите) Плюс для сборки всегда помогает указать, какая ваша целевая платформа/ОС для запуска кода и какой ассемблер вы используете для его компиляции (не стесняйтесь даже скопировать используемые строки команд, поэтому даже тех, которые могут помочь решить проблемы). – Ped7g

+0

Я имею в виду, что есть немного людей, которые будут смотреть на ваш источник и иметь одну и ту же среду, чтобы они могли просто скопировать/вставить его, скомпилировать и увидеть вашу проблему вживую.Большинство людей здесь будут использовать свои знания и опыт, чтобы сделать «сухой пробег» в своей голове, и чтобы облегчить им работу, вы должны предоставить все необходимые детали (просто представьте себе, что вы читаете свой вопрос с нулевым знанием о том, как выглядит ваша установка). – Ped7g

ответ

2

С поправкой на add быть заменен mov, как указано в вашем комментарии (Обратите внимание, что строка: добавить ал, [BX] на самом деле мов аль, [BX]) есть только функция позвоните по этикетке EndLoop это не так!

Вы хотите отобразить сумму и используете функцию печати DOS. Эта функция 09h ожидает указателя в DS: DX, который вы не предоставляете!
Даже если вы это сделали, вам все равно придется преобразовать сумму в ее текстовое представление.

Быстрое решение здесь заключалось бы в том, чтобы конкретизировать себя и просто отобразить результат в виде одного символа ASCII. Жёстко сумма 52 и поэтому является отображаемым характером:

EndLoop: 
    mov dl, [sum] 
    mov ah, 02h ;Single character output 
    int 21h 

; -------------------------- 

exit: 
    mov ax, 4c00h 
    int 21h 

один шагом вперед, и мы можем показать «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  ;restore 
int 21h 
1

Я не видит никакой ошибки вообще, код будет суммировать массив, отобразить некоторые случайные sh * t и выйти.

Возможно, вы хотите отобразить результат по сумме товаров?

int 21h, ah=9 отобразит '$' завершенную строку из памяти, на которую указывает dx.

Так что вам нужно две вещи, преобразовать число в [sum] в строку завершенного '$' в конце, а затем установите dx в преобразованной строке перед этой int 21h.

Вы можете попытаться извлечь number2string процедуру здесь: https://stackoverflow.com/a/29826819/4271923

Я бы лично изменить его взять адрес целевого буфера в si в качестве еще одного аргумента вызова (т.е. просто удалить mov si,offset str из тела процедуры.). Как это:

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 

Тогда назвать это в вашей EndLoop вам нужно добавить в сегмент данных numberStr DB 8 DUP (0) иметь некоторый буфер памяти, выделенный для строки и добавить в код:

; 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 ...