Другие языки программирования и технологии

Решение выражения на Ассемблере.

Набрал в текстовом редакторе Начальную программу, которая решает выражение: ((D^2-A)^2\D^2+B)-20; с заданными числами A=10, B=4, D=-23. Нужно как-то через Norton Commander сохранить всё это в форматах asm, obj, lst, сделать листинг, и компанировать с помощью Link.exe. Вот текст Начальной программы: ;--------------------------------------------Поле стека -----------------sseg segment 'stack' db 128 dup (?) sseg ends ;--------------------------------------------Поля даних -----------------dseg segment 'data' text1 db 'Програма стартувала', 13, 10, '$' text2 db '((D^2-A)^2\D^2+B)-20 = $' A dw 0Ah B dw 4 D dw 0E9h rez dw ? dseg ends ;--------------------------------------------Текст програми -------------cseg segment 'code' assume cs:cseg, dsseg, ss:sseg start proc far mov ax, dseg mov ds, ax ;-------------------------------------------------------------------------m1: lea dx, text1 call WrStr mov dx,offset text2 call WrStr ;-------------------------------------------------------------------------m2: mov ax,d mul ax add ax,b mov cx,ax mov ax, D mul ax sub ax, A mul ax div cx sub ax,20 mov rez,ax ;-------------------------------------------------------------------------m3: mov dl, al add dl, 30h mov ah, 02h Int 21h ;-------------------------------------------------------------------------m4: mov ah, 4ch Int 21h Start endp ;-------------------------------------------------------------------------WrStr proc near mov ah, 09h int 21h ret WrStr endp ;-------------------------------------------------------------------------Cseg ends end start Возможно есть где-то ошибки... Помогите кому по силам...
Ну первое, что сразу видно, переменная D инициализируется неправильно!
и реализовано ((D^2-A)^2/(D^2+B))-20, а не ((D^2-A)^2\D^2+B)-20
Олег Казачёк
Олег Казачёк
76 473
Лучший ответ
Мне не нравится вот эта строчка:
assume cs:cseg, dsseg, ss:sseg
Может быть, нужно так:
assume cs:cseg, ds:dsseg, ss:sseg ?

Кстати, да, о переменных: почему не написать, например, так:
A dw 10
...
D dw -23

Если ты набрал этот текст в NC, сохрани его, нажав F2. Это исходный текст программы, который должен иметь расширение .asm
Для получения объектного файла (.оbj) и листинга (.lst) нужно откомпилировать исходник при помощи
MASM или TASM (в зависимости от того, что у тебя есть) . Готовую программу получишь после редактирования связей:
LINK имя_файла. obj
стартУвала - поправьте =)
dsseg в assume не присвоен
rezdw - неинициал. данные лучше помещать в начале сегмента.

d^2 лучше вычислять один раз.

Нет проверки на переполнение (jc)
Нет проверки на div cx если ноль (jcxz)
(не ну если A B D только такие и не меняются - можно проверками пренебречь)

P.S: Ну что бросилось сразу.. . К сож. я ща на линухе и DOS программу не проверю =) Ну да можно DosBox, но..
Ошибок немало.
Во-первых, у вас числа знаковые, а вы используете беззнаковое умножение.
Нужно использовать команду imul вместо mul хотя бы при возведении в квадрат D
Во-вторых, вы очень просто хотите вывести на экран результат вычислений.
Так не получится. Нужно число (493, кстати) преобразовать в цепочку символов, а не выдавать на экран как код символа.

;--------------------------------------------Поле стека -----------------
sseg segment 'stack'
db 128 dup (?)
sseg ends
;--------------------------------------------Поля даних -----------------
dseg segment 'data'
text1 db 'Програма стартувала', 13, 10, '$'
text2 db '((D^2-A)^2\D^2+B)-20 = $'
A dw 0Ah
B dw 4
D dw -23; или -17h
rez dw ?
dseg ends
;--------------------------------------------Текст програми -------------
cseg segment 'code'
assume cs:cseg, ds:dseg, ss:sseg
start proc far
mov ax, dseg
mov ds, ax
;-------------------------------------------------------------------------
lea dx, text1
call WrStr
mov dx,offset text2
call WrStr
;-------------------------------------------------------------------------
mov ax,d
imul ax
mov bx,ax
sub ax,A
mul ax
div bx
add ax,b
sub ax,20
mov rez,ax
;-------------------------------------------------------------------------
;Вывод результата на экран
mov bl,10
div bl
mov bh,ah
cbw
div bl
mov dx,3030h
add dx,ax
mov ah, 02h
Int 21h
mov dl,dh
int 21h
mov dl,30h
add dl,bh
int 21h
;-------------------------------------------------------------------------
mov ah,1; чтобы программа не закрывалась сразу
int 21h; и можно было увидеть результат
mov ah, 4ch
Int 21h
Start endp
;-------------------------------------------------------------------------
WrStr proc near
mov ah,09h
int 21h
ret
WrStr endp
;-------------------------------------------------------------------------
Cseg ends
end start

P.S. метки m1, m2 и т. д. не нужны. У вас они нигде не используются
Данная программа будет корректно работать только с заданными значениями.