Консультация № 142039
23.08.2008, 11:47
0.00 руб.
23.08.2008, 16:54
0 7 2
Уважаемые специалисты, как вывести элементы массива поочередно в строке? После вывода одного элемента очищаю строку для вывода следующего. В результате после ввода (ф. vvod закомментировал) или инициализации massiv dw 123,56,1,0,89,104 получаю
123
563
1 3
0 3
893
104
Код com-проги в приложении:
Если можно, то прокомментируйте Ваш вариант-нужно разобраться, а не только сдать
Заранее спасибо

Приложение:

.386
cseg segment use16
assume cs:cseg
org 100h
main:

;mov ah,09h
;mov dx,offset PriglKVvodu
;int 21h

;call perevodkursora

mov bp,offset string

;mov si,0
;vvodmassiva:
;call vvod
;mov massiv[si],ax
;add si,2 ;к следующему элементу
;call perevodkursora
;dec schetchik
;jnz vvodmassiva

;;call rasshir_vdopkod

;call perevodkursora

mov schetchik,6
mov si,offset massiv
vivodmassiva:

mov bp,offset string

mov ax,[si]
call vivod
add si,2
mov ah,09h
mov dx,offset string
int 21h

mov schetchikstroki,7
ochistkastroki:
mov di,offset string
mov word ptr[di],20h
inc di
dec schetchikstroki
jnz ochistkastroki

call perevodkursora

dec schetchik
jnz vivodmassiva
mov ax,4c00h ;стандартный выход для EXE-проги работает и в COM-проге
int 21h

;ещё один вариант очистки строки вывода
;ochistkastroki proc
;mov di,offset string
;cld
;mov ax,20h ;в отладчике это число подстявлялось вместо элемента массива в ф. vivod
;mov cx,7
;rep stosw
;ret
;ochistkastroki endp

vivod proc
xor cx,cx
xor bx,bx
mov bl,10
.divide:
xor dx,dx
div bx

add dx,'0'
push dx
inc cx
or ax,ax
jnz .divide

.reverse:
pop ax
;stosb
mov [bp],al
inc bp
loop .reverse
ret
vivod endp

perevodkursora proc
lea dx,ent
mov ah,09h
int 21h
ret
perevodkursora endp


vvod proc
xor ax,ax

mov di,0

mov znak,0

myinput:

mov ah,08h ;ввожу и показываю знак числа
int 21h

cmp al,13
je done

cmp al,'+'

jz znakvpamyat

cmp al,'-'

jz znakvpamyat

cmp znak,0
jz null
jmp inpt

null:
cmp al,30h
jnz myinput
;mov si,30h
call vivodsimvola
mov ax,0
mov znak,'+'
jmp vihod

inpt:

cmp al,39h
ja myinput
cmp al,30h
jb myinput
cmp al,30h
jnz b
cmp di,0
jz myinput
;нет
b:
call vivodsimvola

sub al,30h;’0’
xor ah,ah
mov cx,ax
mov ax,di
mov bx,10
mul bx
add ax,cx
mov di,ax
jmp myinput

znakvpamyat:
cmp znak,0
jnz myinput
mov znak,al
call vivodsimvola
jmp myinput

done: mov ax,di

cmp znak,'+'
jnz otritsatel
cmp ax,[VerhGranDiapaz]
jbe vihod
call perevodkursora
call vihodzadiapazon
mov di,0
mov znak,0
jmp myinput
otritsatel:
cmp ax,[NizhGranDiapaz]
jbe vihod
call perevodkursora
call vihodzadiapazon
mov di,0
mov znak,0
jmp myinput

vihod:
ret
vvod endp


vivodsimvola proc
mov ah,02h
mov dl,al
int 21h
ret
vivodsimvola endp


vihodzadiapazon proc
mov ah,09h
mov dx,offset zadiapazon
int 21h
ret
vihodzadiapazon endp


rasshir_vdopkod proc
cmp znak,'+' ;+А?
jz polozhitel ;да
neg ax
polozhitel:
ret
rasshir_vdopkod endp


string db 7 dup(20h),'$'
massiv dw 123,56,1,0,89,104
i dw 0
ent db 13,10,'$' ;перевод курсора на строку ниже
schetchik db 6
zadiapazon db 'The entered number is not included into range of numbers with a sign, enter number again: $'
NizhGranDiapaz dw 128
VerhGranDiapaz dw 127
PerSlag dw 0
PriglKVvodu db 'Enter a sign, number and press Enter:$'
znak db 0 ;вместо регистра si в vvod
schetchikstroki db 7

cseg ends
end main

Обсуждение

Неизвестный
24.08.2008, 12:44
общий
Во-первых, в начале работы по Win XP нужно инициализировать текстовый режим
Код:
 mov ax, 3
int 10h

Во-вторых, "стандартный" выход из EXE далеко не всегда работает в COM - не надо так
В-третьих, плохо понял, что нужно. Поясните. Вам не нравится Ваш вывод?
Неизвестный
25.08.2008, 08:50
общий
это ответ
Здравствуйте, Mishgan!

mov schetchikstroki,7
mov di,offset string
ochistkastroki:
mov byte ptr[di],20h
inc di
dec schetchikstroki
jnz ochistkastroki

сравнив со своим кодом разберётесь
Неизвестный
25.08.2008, 23:05
общий
Boriss, я хотел, чтобы был вывод чисел таких же, что и при инициализации
На счет выхода из EXE: учту
Текстовый режим имеется в виду в командной строке (мои проги под ДОС) или для программирования 32-х разрядных прог?
Mishgan
давно
Старший Модератор
31795
6196
26.08.2008, 12:24
общий
это ответ
Здравствуйте, Mishgan!

Данный цикл в Вашей программе лишний:
Код:
 ochistkastroki:
. . .
jnz ochistkastroki

т.к. получается Вы два раза заполняете свою строку, первый раз когда записываете цифры числа, второй когда записываете пробел. Зачем? Вам достаточно только добавить команду:
Код:
loop .reverse
mov byte ptr[bp],'$';записываем маркер конца строки
ret

Тем самым Вы записываете после своего сформированого числа, маркер конца строки для функции 09h прерывания 21h.
Ещё как совет, можно иначе записать саму строку вывода:
Код:
ent db 13,10
string db 7 dup(20h),'$'

Формируете число как в программе с метки string , а вот выводите начиная с метки ent . Таким образом можно выбросить ещё код п/п perevodkursora.
Удачи!
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
26.08.2008, 21:01
общий
Под XP без инициализации текстового режима вывод не виден. СОМ - это ВСЕГДА DOS, "обычный" EXE (точнее, MZ-файл, от того, что в начале стоят эти две буквы, в отличие от PE, NE-файлов) - это тоже DOS

Далее, BP лучше не использовать так. Это специальный регистр для работы со стеком в подпрограммах. Потом поймете
А я не понял (нет времени анализировать): Ваша проблема не исчезла после ответов?
давно
Старший Модератор
31795
6196
26.08.2008, 21:26
общий
Boriss:
Цитата: 422
в отличие от PE, NE-файлов
, правда? эти фалы тоже начинаются с MZ-заголовка вернее заглушки.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
27.08.2008, 22:21
общий
Boriss, проблемы больше нет
После того, как вставил иниц-ю тест. режима после метки main, в командной строке очистился предыд. ввод и прога выдала результат. В этом и есть суть инициализации режима?
Почему прогу под ДОС (например, эту, COM или EXE вер.) на асме нельзя запустить, а проги на Си или Pascal'e под ДОС можно прямо по щелчку мышкой?
Форма ответа