Консультация № 163936
02.04.2009, 00:10
0.00 руб.
0 9 0
Здравствуйте!
У меня задача: если b>=0, то y=a/b+5, если b<0, то a*b/c. Дело в том, что у меня программа работает некорректно: то получается странный результат, то почему-то все время выполняется условие одно и тоже (даже в том случае, когда оно не должно выполняться), в общем, всякая чушь. Очень прошу: посмотрите, пожалуйста, программу, я ее скину в приложение. Свою программу лучше предложить в КРАЙНЕМ случае. Я использую MASM.
Огромное спасибо!

Приложение:
include macro.lib
stack segment para 'stack'
dw 128 dup (?)
stack ends
data segment para 'data'
x0 db 'Esli b>=0, to y=a/b+5 (poslednee delim na pervoe)$'
x6 db 'KRASILNIKOV sozdal programmu$'
x1 db 'Vvedite A: $'
x2 db 'Vvedite B: $'
x4 db 'Vvedite C: $'
x5 db 'Rezultat: $'
a dw ?
b dw ?
data ends
code segment para 'code'
begin proc far
assume cs:code,ds:data,ss:stack
push ds
xor ax,ax
push ax
mov ax, data
mov ds, ax
cls
crlf
crlf
message x0
crlf
crlf
message x6
crlf
xor dx,dx
crlf
message x1
key_$2bin
mov bx,ax
crlf
message x2
key_$2bin
mov cx,0
cmp cx,bx
jge M1
jl m2
M1:
div bx
add ax,5
jmp m3
m2:
mul bx
mov cx,ax
crlf
message x4
key_$2bin
mov bx,ax
mov ax,cx
div bx ; ax=ax/bx
m3:
crlf
message x5
print_number
key_$2bin
mov ax, 4c00h
int 21h
begin endp
code ends
end begin

Обсуждение

давно
Старший Модератор
31795
6196
02.04.2009, 12:28
общий
AkaProc:

Было бы интересно посмотреть на этот макрос key_$2bin правильно ли он вводит отрицательные числа.
Этот участок я бы переписал по другому
Код:
	mov	cx,0
cmp cx,bx
jge M1
jl m2
M1:

К примеру так:
OR bx,bx
JS m2
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
02.04.2009, 15:59
общий
Да, кстати, вот код библиотеки macro.LIB. Извиняюсь, я забыл написать код библиотеки. :)
Код:
bin2$ macro string_name
local fill_buff,clr_dvd,no_more
push dx
push cx
push bx
push si
push ax
lea bx,string_name+1
mov cx,6
fill_buff: mov byte ptr [bx],' '
inc bx
loop fill_buff
mov si,10
or ax,ax
jns clr_dvd
neg ax
clr_dvd: sub dx,dx
div si
add dx,'0'
dec bx
mov [bx],dl
or ax,ax
jnz clr_dvd
pop ax
or ax,ax
jns no_more
dec bx
mov byte ptr [bx],'-'
no_more: mov string_name,6
pop si
pop bx
pop cx
pop dx
endm
video_state macro
mov ah,15
int 10h
endm
print_number macro
local temp,save
jmp save
temp db 7 dup(?)
save: push ds
push cx
mov cx,cs
mov ds,cx
bin2$ temp
print$ temp
pop cx
pop ds
endm
print$ macro string_name
push dx
lea dx,string_name
print$_dx
pop dx
endm
print$_dx macro
local strip,next_c,no_blnk
push ax
push cx
push si
sub cx,cx
mov si,dx
mov cl,[si]
inc si
strip: lodsb
cmp al,' '
jne no_blnk
loop strip
next_c: lodsb
no_blnk: print_al
loop next_c
pop si
pop cx
pop ax
endm
print_al macro
push ax
push bx
push cx
push ax
video_state
pop ax
mov cx,1
mov ah,14
int 10h
pop cx
pop bx
pop ax
endm
key_$2bin macro
local temp,save
jmp save
temp db 7,8 dup(?)
save: push ds
push cx
mov cx,cs
mov ds,cx
in$ temp
$2bin temp+1
pop cx
pop ds
endm
in$ macro string_name
push dx
lea dx,string_name
in$_dx
pop dx
endm
in$_dx macro
push ax
mov ah,0ah
int 21h
pop ax
endm
$2bin macro string_name
local blanks,chk_neg,chk_pos,go_conv,good,no_good,thru
local conv_ab,range,non_dig,digit,end_conv,skipit
push bx
push cx
sub ax,ax
sub ch,ch
mov cl,string_name
lea bx,string_name+1
blanks: cmp byte ptr [bx],' '
jne chk_neg
inc bx
loop blanks
chk_neg: cmp byte ptr [bx],'-'
jne chk_pos
inc bx
dec cx
call conv_ab
jc thru
cmp ax,32768
ja no_good
neg ax
js good
chk_pos: cmp byte ptr [bx],'+'
jne go_conv
inc bx
dec cx
go_conv: call conv_ab
jc thru
cmp ax,32767
ja no_good
good: clc
jnc thru
no_good: stc
thru: pop cx
pop bx
jmp skipit
conv_ab proc
push bp
push bx
push si
mov bp,bx
sub bx,bx
range: cmp byte ptr ds:[bp],'0'
jb non_dig
cmp byte ptr ds:[bp],'9'
jbe digit
non_dig: stc
jc end_conv
digit: mov si,10
push dx
mul si
pop dx
mov bl,ds:[bp]
and bx,0fh
add ax,bx
jc end_conv
inc bp
loop range
clc
end_conv: pop si
pop bx
pop bp
ret
conv_ab endp
skipit: nop
endm
crlf macro
cr
lf
endm
lf macro
push cx
push dx
pos
inc dh
move_cursor dl,dh
pop dx
pop cx
endm
move_cursor macro x,y
local ok,vs
push ax
push dx
mov dl,x
mov dh,y
cmp dh,24
jna ok
sub dh,dh
ok: cmp dl,79
jna vs
sub dl,dl
vs: video_state
mov ah,2
int 10h
pop dx
pop ax
endm
pos macro
push ax
push bx
video_state
mov ah,3
int 10h
pop bx
pop ax
endm
cr macro
push cx
push dx
pos
sub dl,dl
move_cursor dl,dh
pop dx
pop cx
endm
crlf macro
cr
lf
endm
message macro string_name
push dx
lea dx,ds:string_name
message_dx
pop dx
endm
message_dx macro
push ax
mov ah,9
int 21h
pop ax
endm
cls macro
push ax
push bx
push cx
push dx
mov cx,0
mov dh,24
mov dl,79
mov ah,6
mov al,0
mov bh,7
int 10h
pop dx
pop cx
pop bx
pop ax
endm
vv_cls macro
mov ah,0
mov al,2
int 10h
endm
;Ё­ЁжЁ «Ё§ жЁп Јp дЁзҐбЄ®Ј® pҐ¦Ё¬ 
;Ї p ¬Ґвp regim ¤«п pҐ¦Ё¬  640*350 ¤®«¦Ґ­ Ўлвм 10h
;¤«п ў®§ўp в  ў ⥪бв®ў®© pҐ¦Ё¬ ®­ ¤®«¦Ґ­ Ўлвм p ўҐ­ 3h


initega macro regim
push ax
mov ah,0
mov al,regim
; mov al,10h
int 10h
pop ax
endm
;putpixel Ё getpixel - ¬ Єp®бл ¤«п ўлў®¤  Ё з⥭Ёп в®зЄЁ ­  нЄp ­Ґ
;X Ё Y - Є®®p¤Ё­ вл,COLOR - 梥в
;GETPIXEL - ў®§ўp й Ґв 梥⠢ pҐЈЁбвpҐ AL
getpixel macro x,y
local @1,@2
push dx
push cx
mov dx,y
mov cx,x
cmp dx,349
jbe @1
mov dx,349
@1: cmp cx,639
jbe @2
mov cx,639
@2: int 10h
pop cx
pop dx
endm
putpixel macro x,y,color
; local @1,@2
push dx
push cx
push ax
mov ah,0ch
mov al,color
mov cx,x
mov dx,y
int 10h
pop ax
pop cx
pop dx
endm
read_time macro
push ax
mov ah,2ch
int 21h
pop ax
endm
delay macro minutes,seconds,hundredths
local secs,mins,hrs,check,quit
;;
;;ўл¦¤ вм § ¤ ­­®Ґ ўаҐ¬п
;;
push ax
push bx
push cx
push dx
read_time
mov ah,ch
mov al,cl
mov bh,dh
mov bl,dl
add al,minutes
add bh,seconds
add bl,hundredths
cmp bl,100
jb secs
sub bl,100
inc bh
secs: cmp bh,60
jb mins
sub bh,60
inc al
mins: cmp al,60
jb hrs
sub al,60
inc ah
hrs: cmp ah,24
jne check
sub ah,ah
check:read_time
cmp cx,ax
ja quit
jb check
cmp dx,bx
jb check
quit: pop dx
pop cx
pop bx
pop ax
endm
rand macro limit
local strip
push cx
push dx
push ax
mov ah,0
int 1ah
mov ax,dx
mov cl,limit
mov dh,3fh
cmp cl,64
jae strip
shr dh,1
cmp cl,32
jae strip
shr dh,1
cmp cl,16
jae strip
shr dh,1
cmp cl,0
jae strip
shr dh,1
strip: and ah,dh
div cl
mov al,ah
pop cx
mov ah,ch
pop dx
pop cx
endm
sound macro freg,duration
mov di,freg
mov bx,duration
sound_di_bx
endm
sound_di_bx macro
push ax
push bx
push cx
push dx
push di
mov al,0b6h
out 43h,al
mov dx,14h
mov ax,4f38h
div di
out 42h,al
mov al,ah
out 42h,al
in al,61h
mov ah,al
or ah,3
out 61h,al
wait: mov cx,2801
spkr_on:loop spkr_on
dec bx
jnz wait
mov al,ah
out 61h,al
pop di
pop dx
pop cx
pop bx
pop ax
endm
beep macro
sound 1000,50
endm
Sline macro X1,Y1,PX,PY,Count,Symbol
local @1
Mov DL,X1
Mov DH,Y1
Mov CX,Count
Mov Al,Symbol
@1: Move_Cursor
Print_al
Add DL,PX
Add DH,PY
Loop @1
endm
inkey_i macro
push cx
push ax
mov ah,8
int 21h
pop cx
pop ah,ch
pop cx
endm

Если не сложно, объясните, пожалуйста, почему Вы написали именно так:
OR bx,bx
JS m2 ?
давно
Старший Модератор
31795
6196
02.04.2009, 16:08
общий
команда OR устанавливает флаги
CF=0
OF=0
SF=1 если меньше нуля,
ZF=1 если равно нулю
PF=1 если число четное
AF=не определен

команда JS проверяет флаг SF
Вот и всё.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Старший Модератор
31795
6196
02.04.2009, 18:25
общий
AkaProc:
Код:
	message x2
key_$2bin
or ax,ax
js m2
M1:
xchg ax,bx
div bx
add ax,5
jmp m3

Посмотрите этот участок кода, у Вас В АХ введенное число В, а в ВХ ранее введенное А.
добавте выделенную команду.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
02.04.2009, 21:36
общий
Спасибо Вам за ответ!
Я попробовал добавить выделенную синим команду, протестировал, а потом попробовал заменить этот участок кода на такой, как Вы написали. Запустил. Если я добавлю Вашу строку, то у меня получается верный результат, если я введу положительное число первым, если отрицательное ввести первым (число А), то получается какая-то чушь, типа -2*2=132 или что-то типа этого. На вторую метку не перескакивает. Если я оставлю свои строки, где у меня:
mov cx,0
cmp cx,bx
jge M1
jl m2
и добавлю Вашу строку, то он всегда перескакивает на метку м2 вне зависимости ни от чего, но результат получается полным бредом в любом случае.
Возможно, я рассказал не очень понятно, короче, вот текущий код, попробуйте запустить:
Код:

include macro.lib
stack segment para 'stack'
dw 128 dup (?)
stack ends
data segment para 'data'
x0 db 'Esli b>=0, to y=a/b+5 (poslednee delim na pervoe)$'
x6 db 'KRASILNIKOV sozdal programmu$'
x1 db 'Vvedite A: $'
x2 db 'Vvedite B: $'
x4 db 'Vvedite C: $'
x5 db 'Rezultat: $'
a dw ?
b dw ?
data ends
code segment para 'code'
begin proc far
assume cs:code,ds:data,ss:stack
push ds
xor ax,ax
push ax
mov ax, data
mov ds, ax
cls
crlf
crlf
message x0
crlf
crlf
message x6
crlf
xor dx,dx
crlf
message x1
key_$2bin
mov bx,ax
crlf
message x2
key_$2bin
mov cx,0
cmp cx,bx
jge M1
jl m2
M1:
xchg ax,bx
div bx
add ax,5
jmp m3
m2:
mul bx
mov cx,ax
crlf
message x4
key_$2bin
mov bx,ax
mov ax,cx
div bx ; ax=ax/bx
m3:
crlf
message x5
print_number
key_$2bin
mov ax, 4c00h
int 21h
begin endp
code ends
end begin

Спасибо за помощь. :)
давно
Старший Модератор
31795
6196
02.04.2009, 21:56
общий
Вы не поняли что нужно проверять, после key_$2bin число находится в АХ, а не в ВХ(там число А), заметьте я проверяю именно АХ в строках: or ax,ax - js m2, сорри, что сразу не выделил и этот участок.


если b>=0, то y=a/b+5
Допустимые параметры числа В есть и 0, т.е. Вы разрешаете деление на ноль?
Тоже касается и числа С
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
04.04.2009, 12:47
общий
Извиняюсь за задержку ответа.
Нет, я не разрешаю деление на 0, но я и не ввожу таких чисел, чтобы получалось деление на 0, меня интересует проблема, почему у меня сравнение неверно выполняется и результат деления какой-то странный, тоже самое касается умножения. Я делал много экспериментов, но так ничего и не выявил. Я просто не могу понять, почему это вообще может происходить. А может быть такое, что это связано с тем, что есть возможность деления на 0? Я просто не понимаю, в чем ошибка. Сам исправить пока не могу. Вообще, я думал, что это может быть связано с тем, что я пользуюсь различными командами, вызываемыми из библиотеки, а они пользуются РОНом и затирают мой результат, поэтому я попробовал заносить результат в переменные, однако ничего не изменилось. Пока не знаю как быть. Что-то я тут намудрил... Посмотрите, пожалуйста.
Код:

include macro.lib
stack segment para 'stack'
dw 128 dup (?)
stack ends
data segment para 'data'
x0 db 'Esli b>=0, to y=a/b+5 (poslednee delim na pervoe)$'
x6 db 'KRASILNIKOV sozdal programmu$'
x1 db 'Vvedite A: $'
x2 db 'Vvedite B: $'
x4 db 'Vvedite C: $'
x5 db 'Rezultat: $'
a db ?
b db ?
c db ?
data ends
code segment para 'code'
begin proc far
assume cs:code,ds:data,ss:stack
push ds
xor ax,ax
push ax
mov ax, data
mov ds, ax
cls
crlf
crlf
message x0
crlf
crlf
message x6
crlf
crlf
message x1
key_$2bin
mov b,al
crlf
message x2
key_$2bin
mov a,al
mov bl,b
cmp bl,0
ja M1
jb m2
M1 label near
xchg ax,bx
xor dx,dx
xor ax,ax
mov al,a
div b
add ax,5
jmp m3
m2 label near
xchg ax,bx
xor ax,ax
mov al,a
mul b
mov c,al
crlf
message x4
key_$2bin
xor dx,dx
xor bx,bx
mov bl,al
mov al,c
div bl ; ax=ax/bx
m3:
crlf
message x5
print_number
key_$2bin
mov ax, 4c00h
int 21h
begin endp
code ends
end begin
давно
Старший Модератор
31795
6196
07.04.2009, 11:39
общий
AkaProc:

mul и div команды для беззнаковых чисел, Вам нужно использовать команды для знаковых чисел, т.е. imul и idiv
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
08.04.2009, 15:55
общий
Спасибо, возможно, вечером попробую.
Форма ответа