Ввод данных в ASM (i8086)
Пользователи, просматривающие топик: none
|
Зашли как: Guest
|
Имя |
Сообщение |
<< Старые топики Новые топики >> |
|
|
Ввод данных в ASM (i8086) - 2008-12-21 12:21:59.830000
|
|
|
AchtungPartizanen
Сообщений: 38
Оценки: 0
Присоединился: 2007-10-25 20:54:58.030000
|
Вопрос такой. Надо ввести ряд переменных и выполнить с ними определенные действия. Прогу уже написал, но она нифига не работает, при запуске просто ничего не происходит (т.е. окно командной строки появляется, в нем информация о том, что программа скомпилена и отлинкована, "Для продолжения нажмите любую клавишу. . ." и после нажатия окно закрывается), а при дебаге появляется ошибка вот такого вида (см. скрин) stseg segment para stack
dw 16 dup(?)
stseg ends
dseg segment para
N equ 7 ;определяем константу для транслятора - число вводимых переменных
a dw 2
da dw 1 ;приращение
cd dw 5 ;число повторений
b dw 5
c dw 8
d dw 11
e dw 14
y dw ? ;конечное значение
dseg ends
cseg segment para
lab1 proc far
assume cs:cseg,ds:dseg,ss:stseg
push ds
mov ax,0
push ax
mov ax,dseg
mov ds,ax
;------------------ ввод переменных
call far ptr input ;вызываем процедуру ввода
;------------------ вычисление значений
mov bx,0 ;регистр для подсчета значения
lea dx,a ;сюда копируется адрес первого элемента (a)
push dx
call near ptr ariph ;вызвать процедуру вычисления
pop bx ;извлекаем из стека результат в регистр
mov y,bx ;отправить значение по адресу y
ret
lab1 endp
;------------------ процедура ввода переменных
input proc far
BUF_IN db 10,10 dup (0) ; буфер ввода (до 10 символов)
NEG_IN db 0 ; признак "положительно/отрицательно"
MES_IN db 13,10,'Введите число: $' ; запрос на ввод
mov cx, N ; загрузка числа переменных
mov di, 0 ; загрузка смещения адреса переменной
CYCL1:
push cx ; сохраняем счетчик внешнего цикла
lea dx, MES_IN ; загружаем адрес запроса на ввод
mov ah, 9 ; загружаем номер функции DOS
int 21h ; вызываем функцию вывода строки (прерывание 21h)
lea dx, BUF_IN ; загружаем адрес строки ввода
mov ah, 0ah ; загружаем номер функции DOS
int 21h ; вызываем функцию ввода строки (прерывание 21h)
mov byte ptr NEG_IN, 0 ; признак - "число положительно"
cld ; флаг направления - "возрастание адресов"
mov cl, BUF_IN+1 ; загружаем длину введенной строки
mov ch, 0 ; счетчик - в CX
lea si, BUF_IN+2 ; загружаем адрес введенной строки
cmp byte ptr [si], '-' ; число отрицательно?
jne short UNSIGN ; если нет, то переход
mov byte ptr NEG_IN, 1 ; признак - "число отрицательно"
inc si ; пропускаем знак
dec cx ; уменьшаем счетчик
UNSIGN: mov bx, 0 ; исходное значение числа
CYCL2:
mov ax, 10 ; заносим константу 10
mul bx ; умножаем текущее значение числа на 10
mov bx, ax ; текущее значение числа в BX
lodsb ; загрузили очередную цифру
sub al, 30h ; преобразовали из символа в двоичное число
cbw ; преобразовали в слово
add bx, ax ; добавили к текущему значению числа
loop CYCL2 ; выполняем для всех введенных цифр
cmp NEG_IN, 0 ; число положительно?
je short DONE ; если да, то переход
neg bx ; преобразуем в отрицательное число
DONE: ;lea ax,[a] ; загружаем адрес первой переменной а в регистр
mov a+[di], bx ; записываем результат в переменную
add di, 2 ; корректируем смещение
pop cx ; восстанавливаем счетчик внешнего цикла
loop CYCL1 ; выполняем для всех чисел
ret ; возвращаем управление основной процедуре
input endp
;------------------ процедура вычисления значения функции
ariph proc near
assume cs:cseg,ds:dseg,ss:stseg
f dw 7 dup(?) ;промежуточные значения
pop dx ;сохраняем адрес возврата
pop si ;копируем адрес первого операнда
push dx ;возвращаем адрес возврата
mov ax,a
mov bx,b
add ax,bx
mov bx,c
add ax,bx
mov bx,d
add ax,bx
mov bx,e
add ax,bx
mov bx,ax ;результат в bx
pop dx ;извлекаем адрес возврата
push bx ;отправляем результат в стек
push dx ;возвращаем в стек адрес возврата
ret
ariph endp
cseg ends
end lab1
В чем может быть дело?
|
|
|
RE: Ввод данных в ASM (i8086) - 2008-12-24 12:46:23.503333
|
|
|
AchtungPartizanen
Сообщений: 38
Оценки: 0
Присоединился: 2007-10-25 20:54:58.030000
|
Проблема была решена в тот же день своими силами. Что называется, привыкли руки к топорам: это не Плюс Плюсович, переменные надо в сегменте объявлять, а не абы где :)
|
|
|
RE: Ввод данных в ASM (i8086) - 2008-12-24 17:13:54.156666
|
|
|
spikky
Сообщений: 211
Оценки: 0
Присоединился: 2008-10-26 14:50:23.676666
|
quote:
Проблема была решена в тот же день своими силами. Что называется, привыкли руки к топорам: это не Плюс Плюсович, переменные надо в сегменте объявлять, а не абы где Выделенные слова поясните пожалуйста
|
|
|
RE: Ввод данных в ASM (i8086) - 2008-12-25 09:53:25.506666
|
|
|
AchtungPartizanen
Сообщений: 38
Оценки: 0
Присоединился: 2007-10-25 20:54:58.030000
|
А что тут пояснять? Сегмент данных: dseg segment para
;...
dseg ends Никто не мешает объявить точно такой же локальный сегмент в подпрограмме (если глобально выделять не надо)
|
|
|
RE: Ввод данных в ASM (i8086) - 2008-12-25 13:54:48.830000
|
|
|
spikky
Сообщений: 211
Оценки: 0
Присоединился: 2008-10-26 14:50:23.676666
|
Не обязательно определять переменные в сегменте данных, можно и в сегменте с кодом объявить. Более того в программе вообще не может быть сегмента данных.
|
|
|
RE: Ввод данных в ASM (i8086) - 2008-12-25 14:15:31.930000
|
|
|
AchtungPartizanen
Сообщений: 38
Оценки: 0
Присоединился: 2007-10-25 20:54:58.030000
|
quote:
ORIGINAL: spikky Не обязательно определять переменные в сегменте данных, можно и в сегменте с кодом объявить. Более того в программе вообще не может быть сегмента данных. 1. Вообще-то, если ты не заметил, то я в начале их и объявлял в сегменте с кодом - результатом чего и стало появление данной темы 2. Ага. Если и переменных нет:)
|
|
|
RE: Ввод данных в ASM (i8086) - 2008-12-25 17:36:40.353333
|
|
|
spikky
Сообщений: 211
Оценки: 0
Присоединился: 2008-10-26 14:50:23.676666
|
Блин я ему про одно… вообщем почитай учебники по ассемблеру…
|
|
|
RE: Ввод данных в ASM (i8086) - 2008-12-27 11:47:45.936666
|
|
|
rgo
Сообщений: 7170
Оценки: 281
Присоединился: 2004-09-25 05:14:25
|
quote:
ORIGINAL: AchtungPartizanen quote:
ORIGINAL: spikky Не обязательно определять переменные в сегменте данных, можно и в сегменте с кодом объявить. Более того в программе вообще не может быть сегмента данных. 1. Вообще-то, если ты не заметил, то я в начале их и объявлял в сегменте с кодом - результатом чего и стало появление данной темы Ошибкой было не объявление в сегменте кода, а объявление прямо внутри кода, что приводило к тому, что неинициализированные данные выполнялись процессором. Объявлять данные надо так, чтобы процессор их потом не выполнял. ariph proc near
assume cs:cseg,ds:dseg,ss:stseg
f dw 7 dup(?) ;промежуточные значения переход на метку ariph приведёт к попытке выполнить эти 7x2 байта. Если бы ты память под f выделил бы _перед_ меткой arith, то ничего бы не было страшного. А вообще по логике их надо было бы делать локальными переменными и память под них выделять из стека.
|
|
|
RE: Ввод данных в ASM (i8086) - 2008-12-29 17:21:55.633333
|
|
|
Cep}|{
Сообщений: 1396
Оценки: 0
Присоединился: 2007-06-26 01:11:51.416666
|
window.google_render_ad(); по ссылке троян - не заходите на сайт
|
|
|
|
|