Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Assembler

Автор: akaGM
Дата сообщения: 01.06.2007 15:06
Codename 539

заряжаешь свой код на С с опцией /Fa если используете микрософтный компилятор
и все дела...
Автор: moon6
Дата сообщения: 01.06.2007 20:37
Скажите плз, как исправить ошибки:
mov al, matr[dl] **Error** Illegal indexing mode
je kon **Error** Relative jump out of range by 0023h bytes
mov matr[al], l **Error** Need register in expression
Автор: Qraizer
Дата сообщения: 02.06.2007 17:06
Для адресации (16-битной) могут использоваться только BX, SI и DI. Ещё BP, но он по дефолту юзает SS, а не DS. Ни AL, ни DL для этого не пригодны. Вот ассемблер и ругается. Как же этого не знать - это ж основы...
Команды условных переходов (для процессоров до 386) не умеют прыгать дальше, чем на расстояния -128...+127 байт от следующей на ними инструкции. Но это умеет команда безусловного перехода. Замени je kon на
Код: jne neKon
jmp kon
neKon:
Автор: SPY
Дата сообщения: 02.06.2007 17:20
Жаль, что никто не откликнулся на мой зов, но он был скорее от усталости..

Вот что у меня получилось, после некоторых преобразований..
Теперь прога всё считает, но с числами до 32767, и всё потому что у меня сумма исходных чисел всего лишь слово (SumTot dw 0,'$'). Переделывать всё под пару DX:AX и SumTot=DWORD не очень хочется, поэтому необходимо написать проверку на переполнение, и в случае переполнения выводить ошибку "Buffer overflow!".. А ещё деление у меня целочисленное, и дробная часть отбрасывается, даже если результат 2,8 - выводится только 2-ка..

Если вы мне подскажите как лучше написать проверку, и трудно ли изменить деление, буду вам премного благодарен!
Заранее благодарю!


[more=ТУТ КОД]
Код: ;Лабораторная работа №3.
;ТЕМА: Ввод-вывод и арифметическая обработка числовых данных.

;ЗАДАНИЕ: Написать программу, выполняющую
; -ввод массива целыx многозначныx чисел со знаком. При вводе осуществляется контроль допустимости вводимыx символов. Ввод предваряется текстовым приглашением.
; -арифметическую и логическую обработку массива чисел по заданию преподавателя.
; -преобразование числового результата в ASCII-строку и отображение на дисплее.

;Индивидуальное задание: (#1)Разделить сумму исходных чисел на максимум из положительных.

    
.MODEL SMALL            ;определение модели памяти
.stack 100h            ;сегмент стека размером в 256 байт

;pointer macro a,b,c         ;положение курсора
;    mov ah,02         ;bh=номер видеостраницы, dh=строка курсора, dl=столбец курсора.
;    mov bh,a
;    mov dh,b
;    mov dl,c
;    int 10h
;endm

input_string macro ist        ;ввод строки символов
    push ax
    push dx
    mov dx,offset ist
    mov ah,0Ah
    int 21h
    pop dx
    pop ax
endm

Out_string macro ost        ;вывод сообщений на экран
    push ax
    push dx
    mov dx,offset ost
    mov ah,9
    int 21h
    pop dx
    pop ax
endm


.data
mess1 db 'Input the number (-29999;+29999): $' ;приглашение ввода числа
mess_err1 db '<< Input error! >>$'        ;сообщение "Ошибка ввода"
mess_err2 db '<< Buffer overflow! >>$'        ;сообщение "Переполнение буфера"
mess2 db 'The sum total of input numbers: $'     ;сообщение "Сумма исходных чисел"
mess3 db 'Maximum of positive number: $'    ;сообщение "Максимум из положительных"
mess4 db 'Result: $'                ;сообщение "Результат"

numbb label byte                ;массив трактуется как байтовый
numbers db 7,?,7 dup(0)                ;вводимые числа
massiv dw 5 dup(0)                ;массив уже введеных чисел
SumTot dw 0,'$'                 ;сумма исходных чисел
MaxPos dw 0,'$'                    ;максимум из положительных
Result dw 0,'$'                    ;результат деления
flag_error EQU 1                ;константа = флаг ошибки
out_str db 6 dup(' '),'$'
perev db 0dh,0ah,'$'

.code
Start:
mov ax,@data                     ;связь регистра DS с сегментом данных через AX
mov ds,ax

;Видеосервис. Вызов Функции 0(ah), режим 3(al), очистка экрана.
mov ah,00
mov al,03
int 10h

;цикл ввода
    xor di,di         ;di - номер числа в массиве
    mov cx,5         ;в cx - размер массива
input:    
    push cx
label_1:
    Out_string mess1
    input_string numbers
    Out_string perev
;call AscToBin
    call DIAPAZON
    cmp bh,flag_error     ;сравним bh и flag_error
    je err1     ;если равен -> сообщение об ошибке ввода

    call DOPUST
    cmp bh,flag_error
    
    je err1

    call AscToBin
    inc di
    inc di
    pop cx
    loop input
    jmp label_2

err1: Out_string mess_err1
    Out_string perev
    jmp label_1

;                ------ >>> здесь арифметическая обработка <<< ------

label_2:            ;сумма исходных чисел
        xor si,si
        xor ax,ax
        xor bx,bx
        xor dx,dx
        mov cx,5
metka:        mov bx,offset [massiv+si]
        add ax,bx
    ;    jo ovr        ;НАПИСАТЬ ПРОВЕРКУ НА ПЕРЕПОЛНЕНИЕ
        inc si
        inc si
        loop metka

        mov SumTot,ax
        Out_string perev
        Out_string mess2
        call BinToAsc
        Out_string out_str
        Out_string perev
        call CLEAN
                ;максимум из положительных
xor si,si
    mov cx,5
;mov si,2
next:        mov ax,offset [massiv+si]
cmp ax,0
jle sled
cmp ax,MaxPos
jle sled
mov MaxPos,ax
sled: inc si
inc si
loop next
Out_string mess3
        mov ax,MaxPos
        call BinToAsc
        Out_string out_str
        Out_string perev
        call CLEAN
            ;результат деления
        xor ax,ax    
xor dx,dx
mov ax,SumTot
        sub dx,dx        
        div MaxPos    
        jo ovr        ;НАПИСАТЬ ПРОВЕРКУ НА ПЕРЕПОЛНЕНИЕ (???)
        mov Result,ax
        Out_string mess4
        call BinToAsc
        Out_string out_str
        Out_string perev
        call CLEAN        
        jmp quit

ovr:        Out_string mess_err2    ;вывод сообщения о переполнении
quit:        mov ah,7        
        int 21h
    
        mov ax,4C00h        ;системный вызов DOS 4Ch: в АН помещается 4Ch, в AL - код возврата
        int 21h

WAIT_KEY proc            ;процедура ожидания нажатия клавиши
mov ah,10h
int 16h
ret
WAIT_KEY endp


DIAPAZON proc            ;проверка диапазона вводимых чисел (-29999;+29999)
                ;буфер ввода - numbers
                ;через bh возвращается флаг ошибки ввода.
xor bh,bh
    cmp [numbers+1],5    ;если ввели менее 5 символов проверим их допустимость
    jb dop

    cmp [numbers+2],2dh    ;если ввели 5 или более символов, проверим является ли первый минусом "-"
    jne plus        ;если первый символ не "-", тогда проверим число символов

    cmp [numbers+1],6    
    jb dop            ;если первый символ "-", а символов меньше 6 проверим допустимость символов
    je first_otr        ;если первый символ "-", и количество равно 6, проверим первую цифру для отрицательных

plus: cmp [numbers+1],6     ;введено 6 символов и первый символ не "-", тогда ошибка.
    je error1         ;ошибка!
    cmp [numbers+2],32h     ;сравним первый символ с "2"
    jna dop             ;если первый <=2 - проверим допустимость символов

error1:    mov bh,flag_error     ;bh = flag_error
    ret

first_otr:
    cmp [numbers+3],32h    ;сравним первый символ с "2"
    jna dop         ;если первый <=2 - проверим допустимость символов
    mov bh,flag_error    ;bh = flag_error
dop:    ret
DIAPAZON endp


DOPUST proc            ;проверка допустимости вводимых символов
                ;буфер ввода - numbers
                ;через bh возвращается флаг ошибки ввода, si - номер символа в строке
    xor bh,bh
xor ah,ah
    xor ch,ch
    mov si,2
    mov cl,[numbers+1]    ;в cl количество введенных символов
over:    mov al,[numbers+si]    ;в al - первый и последующие символы
    cmp al,2dh        ;является ли символ минусом
    jne testdop        ;если не минус - проверка допустимости
    cmp si,2        ;если минус - является ли он первым символом
    jne error2        ;если минус не первый - ошибка!
    jmp lower
testdop:            ;является ли введенный символ цифрой
    cmp al,30h
    jb error2
    cmp al,39h
    ja error2
lower:    inc si
    loop over
    jmp exit

error2:    mov bh,flag_error    ;при недопустимости символа bh = flag_error
exit:    ret    
DOPUST endp


AscToBin proc            ;преобразование строки в число
                ;в cx количество введенных символов
                ;в bx - номер символа начиная с последнего
                ;буфер чисел - massiv, в di - номер числа в массиве
    xor ch,ch
    mov cl,[numbers+1]
    xor bh,bh
    mov bl,cl
    dec bl
    mov si,1         ;в si вес разряда
n1:    mov al,[numbers+2]+bx
    xor ah,ah
    cmp al,2dh        ;проверим знак числа
    je otr         ;если число отрицательное
    sub al,30h
    mul si
    add [massiv+di],ax
    mov ax,si
    mov si,10
    mul si
    mov si,ax
    dec bx
    loop n1
    jmp n2

otr:    neg [massiv+di]        ;представим отрицательное число в дополнительном коде
n2:    ret
AscToBin endp
        
    
BinToAsc PROC            ;преобразование числа в строку
                ;число передается через ax
    xor si,si
    add si,5
    mov bx,10
    push ax
    cmp ax,0
    jnl m1
    neg ax
m1:    cwd
    idiv bx
    add dl,30h
    mov [out_str+si],dl
    dec si
    cmp ax,0
    jne m1
    pop ax
    cmp ax,0
    jge m2
    mov [out_str+si],2dh
m2:    ret
BinToAsc ENDP


CLEAN PROC
    mov cx,6        ;очистка буфера вывода
    xor si,si
clear:    mov [out_str+si],' '
    inc si
    loop clear
    ret
CLEAN ENDP

end Start
Автор: Abs62
Дата сообщения: 02.06.2007 20:21
SPY

Цитата:
Если вы мне подскажите как лучше написать проверку

А чем JO (или JC) не нравятся?

Цитата:
трудно ли изменить деление

Ну, навскидку - умножить остаток на 10 и снова разделить на делитель - получится первая цифра после запятой. Ещё раз это проделать - вторая. Ещё - третья, и так далее, до достижения требуемой точности или пока остаток не окажется нулевым.
Автор: moon6
Дата сообщения: 03.06.2007 10:47
Qraizer

Цитата:
Для адресации (16-битной) могут использоваться только BX, SI и DI. Ещё BP, но он по дефолту юзает SS, а не DS. Ни AL, ни DL для этого не пригодны. Вот ассемблер и ругается. Как же этого не знать - это ж основы...

Забыл или на лекции пропустил это..

Пасиб


Так.. Ошибки вроде исправил, но теперь другая проблема.
Прога омпилится, запускается, но при вводе числа вылетает окошко с ошибкой:

Код: <имя ехе'шника>
Процессор NTVDM обнаружил недопустимую инструкцию.
CS:0000 IP:0077 OP:f0 37 05 10 02 Для завершения работы приложения нажмите кнопку "Закрыть".
Автор: SPY
Дата сообщения: 03.06.2007 12:43
Abs62
Спасибо за советы..

Кое-что подправил ещё..
Получилось пока не всё..
1) Деление отрицательного числа приводит к не правильному результату.. (!)
2) Деление всё ещё целочисленное.. (остаток теряется) [пока не правил]

Самое важное по пункту (1), никак не найду ошибку..

[more=код программы]
Код: ;Лабораторная работа №3.
;ТЕМА: Ввод-вывод и арифметическая обработка числовых данных.

;ЗАДАНИЕ: Написать программу, выполняющую
; -ввод массива целыx многозначныx чисел со знаком. При вводе осуществляется контроль допустимости вводимыx символов. Ввод предваряется текстовым приглашением.
; -арифметическую и логическую обработку массива чисел по заданию преподавателя.
; -преобразование числового результата в ASCII-строку и отображение на дисплее.

;Индивидуальное задание: (#1)Разделить сумму исходных чисел на максимум из положительных.

    
.MODEL SMALL            ;определение модели памяти
.stack 100h            ;сегмент стека размером в 256 байт

;pointer macro a,b,c         ;положение курсора
;    mov ah,02         ;bh=номер видеостраницы, dh=строка курсора, dl=столбец курсора.
;    mov bh,a
;    mov dh,b
;    mov dl,c
;    int 10h
;endm

input_string macro ist        ;ввод строки символов
    push ax
    push dx
    mov dx,offset ist
    mov ah,0Ah
    int 21h
    pop dx
    pop ax
endm

Out_string macro ost        ;вывод сообщений на экран
    push ax
    push dx
    mov dx,offset ost
    mov ah,9
    int 21h
    pop dx
    pop ax
endm


.data
mess1 db 'Input the number (-29999;+29999): $' ;приглашение ввода числа
mess_err1 db '<< Input error! >>$'        ;сообщение "Ошибка ввода"
mess_err2 db '<< Buffer overflow! >>$'        ;сообщение "Переполнение буфера"
mess2 db 'The sum total of input numbers: $'     ;сообщение "Сумма исходных чисел"
mess3 db 'Maximum of positive number: $'    ;сообщение "Максимум из положительных"
mess4 db 'Result: $'                ;сообщение "Результат"
mess5 db 'ERROR! Division by zero!$'         ;сообщение "Ошибка! Деление на ноль!"

numbb label byte                ;массив трактуется как байтовый
numbers db 7,?,7 dup(0)                ;вводимые числа
massiv dw 5 dup(0)                ;массив уже введеных чисел
SumTot dw 0,'$'                 ;сумма исходных чисел
MaxPos dw 0,'$'                    ;максимум из положительных
Result dw 0,'$'                    ;результат деления
flag_error EQU 1                ;константа = флаг ошибки
out_str db 6 dup(' '),'$'
perev db 0dh,0ah,'$'                ;перевод строки
bigword dw 32768

.code
Start:
mov ax,@data                     ;связь регистра DS с сегментом данных через AX
mov ds,ax

;Видеосервис. Вызов Функции 0(ah), режим 3(al), очистка экрана.
mov ah,00
mov al,03
int 10h

;цикл ввода
    xor di,di         ;di - номер числа в массиве
    mov cx,5         ;в cx - размер массива
input:    
    push cx
label_1:
    Out_string mess1
    input_string numbers
    Out_string perev
;call AscToBin
    call DIAPAZON
    cmp bh,flag_error     ;сравним bh и flag_error
    je err1     ;если равен -> сообщение об ошибке ввода

    call DOPUST
    cmp bh,flag_error
    
    je err1

    call AscToBin
    inc di
    inc di
    pop cx
    loop input
    jmp label_2

err1: Out_string mess_err1
    Out_string perev
    jmp label_1

;     ----- ----- ----- ----- >>> ниже арифметическая обработка <<< ----- ----- ----- -----

label_2:            ;сумма исходных чисел
        xor si,si
        xor ax,ax
        xor bx,bx
        xor dx,dx
        mov cx,5
metka:        mov bx,offset [massiv+si]
        add ax,bx
        jno storey_lower    ;проверка на переполнение буфера
        jmp ovr
storey_lower:            
        cmp ax,bigword
        jnle storey_lower2
        jmp ovr
storey_lower2:
        inc si
        inc si
        loop metka

        mov SumTot,ax
        Out_string perev
        Out_string mess2
        call BinToAsc
        Out_string out_str
        Out_string perev
        call CLEAN
                ;максимум из положительных
xor si,si
    mov cx,5
next:        mov ax,offset [massiv+si]
cmp ax,0
jle sled
cmp ax,MaxPos
jle sled
mov MaxPos,ax
sled: inc si
inc si
loop next
Out_string mess3
        mov ax,MaxPos
        call BinToAsc
        Out_string out_str
        Out_string perev
        call CLEAN
                ;деление SumTot на MaxPos
        xor ax,ax    
xor dx,dx
mov ax,SumTot
        sub dx,dx

        cmp MaxPos,0        ;проверка значения MaxPos
        je divis
        jmp storey_lower3
divis:         Out_string perev
        out_string mess5     ;вывод сообщения "Ошибка! Деление на ноль!"
        jmp quit
storey_lower3:    
        div MaxPos
        mov Result,ax
        Out_string mess4
        call BinToAsc
        Out_string out_str
        Out_string perev
        call CLEAN    
        jmp quit

ovr:        Out_string mess_err2    ;вывод сообщения о переполнении
quit:        mov ah,7    
        int 21h
    
        mov ax,4C00h        ;системный вызов DOS 4Ch: в АН помещается 4Ch, в AL - код возврата
        int 21h


WAIT_KEY proc            ;процедура ожидания нажатия клавиши
mov ah,10h
int 16h
ret
WAIT_KEY endp


DIAPAZON proc            ;проверка диапазона вводимых чисел (-29999;+29999)
                ;буфер ввода - numbers
                ;через bh возвращается флаг ошибки ввода.
xor bh,bh
    cmp [numbers+1],5    ;если ввели менее 5 символов проверим их допустимость
    jb dop

    cmp [numbers+2],2dh    ;если ввели 5 или более символов, проверим является ли первый минусом "-"
    jne plus        ;если первый символ не "-", тогда проверим число символов

    cmp [numbers+1],6    
    jb dop            ;если первый символ "-", а символов меньше 6 проверим допустимость символов
    je first_otr        ;если первый символ "-", и количество равно 6, проверим первую цифру для отрицательных

plus: cmp [numbers+1],6     ;введено 6 символов и первый символ не "-", тогда ошибка.
    je error1         ;ошибка!
    cmp [numbers+2],32h     ;сравним первый символ с "2"
    jna dop             ;если первый <=2 - проверим допустимость символов

error1:    mov bh,flag_error     ;bh = flag_error
    ret

first_otr:
    cmp [numbers+3],32h    ;сравним первый символ с "2"
    jna dop         ;если первый <=2 - проверим допустимость символов
    mov bh,flag_error    ;bh = flag_error
dop:    ret
DIAPAZON endp


DOPUST proc            ;проверка допустимости вводимых символов
                ;буфер ввода - numbers
                ;через bh возвращается флаг ошибки ввода, si - номер символа в строке
    xor bh,bh
xor ah,ah
    xor ch,ch
    mov si,2
    mov cl,[numbers+1]    ;в cl количество введенных символов
over:    mov al,[numbers+si]    ;в al - первый и последующие символы
    cmp al,2dh        ;является ли символ минусом
    jne testdop        ;если не минус - проверка допустимости
    cmp si,2        ;если минус - является ли он первым символом
    jne error2        ;если минус не первый - ошибка!
    jmp lower
testdop:            ;является ли введенный символ цифрой
    cmp al,30h
    jb error2
    cmp al,39h
    ja error2
lower:    inc si
    loop over
    jmp exit

error2:    mov bh,flag_error    ;при недопустимости символа bh = flag_error
exit:    ret    
DOPUST endp


AscToBin proc            ;преобразование строки в число
                ;в cx количество введенных символов
                ;в bx - номер символа начиная с последнего
                ;буфер чисел - massiv, в di - номер числа в массиве
    xor ch,ch
    mov cl,[numbers+1]
    xor bh,bh
    mov bl,cl
    dec bl
    mov si,1         ;в si вес разряда
n1:    mov al,[numbers+2]+bx
    xor ah,ah
    cmp al,2dh        ;проверим знак числа
    je otr         ;если число отрицательное
    sub al,30h
    mul si
    add [massiv+di],ax
    mov ax,si
    mov si,10
    mul si
    mov si,ax
    dec bx
    loop n1
    jmp n2

otr:    neg [massiv+di]        ;представим отрицательное число в дополнительном коде
n2:    ret
AscToBin endp
        
    
BinToAsc PROC            ;преобразование числа в строку
                ;число передается через ax
    xor si,si
    add si,5
    mov bx,10
    push ax
    cmp ax,0
    jnl m1
    neg ax
m1:    cwd
    idiv bx
    add dl,30h
    mov [out_str+si],dl
    dec si
    cmp ax,0
    jne m1
    pop ax
    cmp ax,0
    jge m2
    mov [out_str+si],2dh
m2:    ret
BinToAsc ENDP

CLEAN proc
    mov cx,6        ;очистка буфера вывода
    xor si,si
clear:    mov [out_str+si],' '
    inc si
    loop clear
    ret
CLEAN endp

end Start
Автор: Abs62
Дата сообщения: 03.06.2007 13:14
SPY

Цитата:
1) Деление отрицательного числа приводит к не правильному результату.. (!)

Для знакового деления используется idiv. div - это деление беззнаковое.
Автор: SPY
Дата сообщения: 03.06.2007 16:24
Abs62
Если бы я не пробовал ))
пока не вышло..
Автор: Abs62
Дата сообщения: 03.06.2007 16:56
SPY
Вот [more=пример]
Код: .model    small
.stack    100h
DIGITS_AFTER_POINT = 5
.data
    buf    db    5 dup (0)
    result    db    20 dup (0)
    digits    db    '.',DIGITS_AFTER_POINT dup (0)
.code
Decimals    proc    near
;перевод остатка от деления в дробную часть
;на входе:
;    ax - остаток
;    bx - делитель
;
    push    di
    push    si
;обнуление выходного массива символов
    lea    di,digits
    inc    di
    push    ax
    mov    al,'0'
    mov    cx,DIGITS_AFTER_POINT
    rep    stosb
    pop    ax
;вычисление дробной части
    lea    di,digits
    inc    di
    mov    si,10
    mov    cx,DIGITS_AFTER_POINT
@@1_1:
    mul    si
    div    bx
    add    al,'0'
    stosb
    mov    ax,dx
    or    ax,ax
    loopnz    @@1_1
    pop    si
    pop    di
    ret    
Decimals    endp
;
Divide    proc    near
;знаковое деление с занесением результата в строку
;на входе:
;    ax - делимое
;    bx - делитель
;
    push    di
    push    si
    lea    di,result
    cld
    cwd
    idiv    bx
    test    ax,8000h
    jz    @@2_1
;Результат отрицательный - записываем '-' в строку и переводим его в положительный
    push    ax
    mov    al,'-'
    stosb
    pop    ax
    neg    ax
    neg    dx
@@2_1:
    push    dx
    push    bx
;
    push    di
;Перевод целой части результата в строку
    lea    di,buf
    xor    cx,cx
    mov    bx,10
@@2_2:
    xor    dx,dx
    div    bx
    push    ax
    mov    ax,dx
    add    al,'0'
    stosb
    inc    cx
    pop    ax
    or    ax,ax
    jnz    @@2_2
    mov    si,di
    dec    si
    pop    di
@@2_3:
    mov    al,[si]
    dec    si
    stosb
    loop    @@2_3
;
    pop    bx
    pop    ax
;получение дробной части результата
    call    Decimals
;дописывание дробной части в результирующую строку
    lea    si,digits
    mov    cx,DIGITS_AFTER_POINT+1
    rep    movsb
    mov    al,0Dh
    stosb
    mov    al,0Ah
    stosb
    mov    al,'$'
    stosb
;
    pop    si
    pop    di
    retn
Divide    endp
START:
    mov    ax,@data
    mov    ds,ax
    mov    es,ax
    mov    ax,-12345    ;делимое
    mov    bx,33    ;делитель
    call    Divide
    lea    dx,result
    mov    ah,9
    int    21h
    mov    ax,4C00h
    int    21h
end    START
Автор: Qraizer
Дата сообщения: 04.06.2007 16:24
moon6
Исходники не полные. Кроме того, я не имею ни желания, ни времени в них разбираться - убогое форматирования и отсутствие комментов делает из текста винегрет. Из того, что бросилось в глаза: не указаны аттрибутов сегментов (кроме стекового); не вводятся M и N; start не объявлена процедурой. И вообще - для отлова глюков существуют отладчики, а форумы - немного для других целей.
Автор: SPY
Дата сообщения: 05.06.2007 08:21
Abs62
Спасибо за пример..
Хоть он мне и не помог, но за содействие спасибо..
Все вчера дописал... Все теперь работает отлично.
Если кому интересно, выложу код..
Даже графику уже начал писать..
Автор: moon6
Дата сообщения: 05.06.2007 16:10
Qraizer

Цитата:
Исходники не полные. Кроме того, я не имею ни желания, ни времени в них разбираться - убогое форматирования и отсутствие комментов делает из текста винегрет. Из того, что бросилось в глаза: не указаны аттрибутов сегментов (кроме стекового); не вводятся M и N; start не объявлена процедурой. И вообще - для отлова глюков существуют отладчики, а форумы - немного для других целей

На другом компе всё заработало
Автор: Konstantin555
Дата сообщения: 05.06.2007 21:35
Большая просьба помочь с написанием "обработчика" массива.
Обработчик массива должен при нахождении элемента со значением "0" увеличивать счётчик на "1"

Шапка к коду здесь: [more]
Title Second
model small
stack 100h
.data
a db ?
tmp db ?
x db 1,0,2,3
db 2,1,0,0
db 0,2,3,0
db 2,5,2,0
.code
start:
mov AX,@data
mov DS,AX

XOR SI,SI

mov cx,15
.....................................................

mov AH,04CH
int 21h
end
[/more]
Где вместо многоточия должен быть код (возможно цикл)

Пробывал так: [more]
mov cx,15
cycl:
mov tmp,x[cx]
cmp tmp,0
jz m1
LoopNZ cycl
m1: add SI,1
[/more]
Но результат не верен....
Автор: grek99
Дата сообщения: 05.06.2007 22:49
Народ кто нибудь сможет помочь?
Ассемблер вообще в первый раз вижу а надо 2 программки написать:

3,27 по теме "Использование прерываний в BIOS"
Написать программу для ввода даты по запросу "введите дату (дд/мм/гг), введенную дату вывести в правом нижнем углу.

3,34 Организовать в ввод с клавиатуры пароля (с помощью 0-ой функции 16h прерывания). На экране отображать вместо вводимых символов знак '*'. По нажатию клавиши Enter программа выводит на экран введенный пароль и выходит.
Автор: moon6
Дата сообщения: 07.06.2007 10:45
Опять подобная ошибка.. CS:0126 IP:0667. Сократил код до минимума для выяснения куска кода, где может быть ошибка.

Код: stak segment para stack 'stak'
dw 64 dup (?)
stak ends

data segment para public 'data'
matr db 100 dup(?)
str3 db 100 dup(?)
n db ?
m db ?
nm db ?
i db ?
k db ?
diag db ?
l db ?
data ends
public preobr
code segment para public 'code'
assume cs:code,ss:stak,ds:data
preobr proc far

push bp
mov bp,sp
push bx
push cx
push dx
push di
push si

mov ax,data
mov ds,ax
push ds
xor ax,ax
add bp,6


pop ds
pop si
pop di
pop dx
pop cx
pop bx
pop bp
ret

preobr endp
code ends
end
Автор: Qraizer
Дата сообщения: 07.06.2007 14:29
Ты хоть сам посмотрел, что написал:
Цитата:

Код: preobr proc far

push bp
mov bp,sp
push bx
push cx
push dx
push di
push si

mov ax,data
mov ds,ax ; модификация DS
push ds ; сохранение DS после модификации??
xor ax,ax
add bp,6 ; это зачем?


pop ds
pop si
pop di
pop dx
pop cx
pop bx
pop bp
ret

preobr endp
Автор: moon6
Дата сообщения: 07.06.2007 16:31

Цитата:
Вместо прибавления к BP лучше пользоваться базовой индексацией: нижний параметр - MOV AX, [BP+6]; следующий - MOV AX, [BP+8] итд. Если ты будешь менять BP, то в оверлейной программе у тебя упадёт менеждер оверлеев. Сильно упадёт. Потому что при подгрузке и выгрузке оверлейных модулей он трассирует стек на предмет процедур и функций, которые в данный момент им выгружены, и он рассчитывает по адресу [BP] найти предыдущий стековый фрейм, CS:IP которого ему и нужны. Стек трассируется по самого дна. Не надо привыкать создавать ему проблемы.

К BP прибавляется 6, чтобы брать данные сразу, без смещения. Нам так на лекции объяснили. Толку от этого немного, но и вреда не должно быть, все в группе делают так, и ничего, всё работает. Да и в предыдущих прогах делал также, всё работало.
ПСы: Этот самый фрейм он разве не по адресу [SP] ищет??
Автор: Qraizer
Дата сообщения: 08.06.2007 13:59
Опять двадцать пять... Ну почему я должен что-то говорить неоднократно, чтоб меня услышали...
Цитата:
Нам так на лекции объяснили. Толку от этого немного, но и вреда не должно быть, все в группе делают так, и ничего, всё работает. Да и в предыдущих прогах делал также, всё работало.
Ну и что? По-твоему преподаватели не ошибаются? Задай ему вопрос, почему никто в мире этого не делает, а он он учит, что надо именно так. И будет ли это работать в оверлейной программе и почему. Поверь, оверлейному менеждеру это не понравится, и он не замедлит тебе об этом сообщить падением программы. Не веришь - так проверь. Впрочем, я допускаю, что ситуация ...несколько частная. Но
Цитата:
...Не надо привыкать создавать ему проблемы.
Плохая привычка писать так, что в некоторых ситуациях код не будет работоспособен. Никогда нельзя знать заранее, пригодится ли когда-нибудь этот код тебе или кому-то ещё.
Автор: yellowair
Дата сообщения: 12.06.2007 16:35
поможите люди добрые,
Дорогие жители форума очень нужна помощь в написание данных программ на TASM, плям очень нужна проги практически идентичны, но есть 1 но некогда особо разбираться в языке,
1.Составить резидентную программу генерации звука различной частоты при нажатии нескольких буквенных клавиш компьютера
2.Составить резидентную программу генерации звуков различной частоты при нажатии одной из функциональных и цифровых клавиш компьютера,
и на посошок
3.Составить программу озвучивания нескольких символьных клавиш с ис-пользованием постобработчика прерываний
заранее спасибо.
ОЧЕНЬ НУЖНА ПОМОЩЬ
Автор: Abs62
Дата сообщения: 12.06.2007 16:49
yellowair

Цитата:
но некогда особо разбираться в языке,

Тады ой. Попробуй поспрошать в форуме, где за решения платят. А здесь помогают тем, кто сам хочет учиться.
Автор: yellowair
Дата сообщения: 13.06.2007 08:57
Abs62

Цитата:
....где за решения платят. ...помогают тем, кто сам хочет учиться.

как бы тебе по ласковей сказать, ru-board всегда был форумом не жмотов а хороших людей, а если тебе что то давит, тогда и не отвечай. я тебе в следующий раз скажу сходи в магазинчик да прикупи софта.
По существу время поджимает, ясно дело надо сдать срочно. Естественно не ради на живы, а для себя любимого, и как полагается, все равно в том что вы мне предоставите все равно нужно будет разобраться на достойном уровне.
P/S/
"барыгам" лучше у себя на сайтах сидеть, и не ходить в приличные места.
Автор: Abs62
Дата сообщения: 13.06.2007 10:17
yellowair

Цитата:
Естественно не ради на живы, а для себя любимого, и как полагается, все равно

Слово "нажива" пишется вместе. Но это мелочи. Я никогда не стану помогать тому, кто пытается сдать зачёт, ни хрена понимая в сути процесса. Вот из этого и исходи. Помочь разобраться - поможем, а на заявления типа "Нука - быстро смантулите мне программу" получишь ответ горного эха - "Мать, мать, мать...!"
Автор: yellowair
Дата сообщения: 13.06.2007 22:47
Abs62
короче, склиф. не хочешь не помогай, пол проги я уже написал, покрайне мере пищать она уже пищит, остался вопрос резидентности. Как видишь без твоей великой помощи. Слова
Цитата:
Нука - быстро

будешь говорить своей подружке, и то я сомневаюсь что она для тебя что то сделает. Ругаться с тобой не хочется не к чему это. Пословиться есть такая не рой яму другому, сам в нее попадешь. Высказал свое мнение спасиб тебе. Не хочешь не надо ни кто тебя не заставляет.
Автор: rain87
Дата сообщения: 14.06.2007 00:36
yellowair
вместо чтоб ругаться лучше задавай вопросы, что непонятно
Abs62 сказал что писать за тебя всю прогу никто не будет, разве что аццкий альтруист найдётся (типа как я в начале темы напрягался)
а раз ты сам пишешь - то респект, спрашивай, будем отвечать

по поводу резидентности - всё относительно просто
существует инт 31ш, у него во входе в АЛ - код выхода, в ДХ - объём памяти в параграфах (16 байт), сколько остаётся резидентной после ПСП
т.е. прога твоя подменяет вектора, после чего оставляет свой код резидентным. такова теория
Автор: yellowair
Дата сообщения: 15.06.2007 11:45
rain87
спасиб, за ответ, прогу написал.... посмотри если не трудно что тут еще и как можно улучшить

Код:
;air
cseg segment para
assume cs:cseg
org 100h
start: jmp initialize
old9_hndlr label dword ; Старый int 9h handler
old9_off dw ?
old9_seg dw ?
ax_ dw ?
scancode db ?
;------------------------------------------------------------------------
; Новый обработчик
;------------------------------------------------------------------------
new9_hndlr proc
mov ax_,ax ; Сохраняем ax регистр.
xor ax,ax ; Обнуляем ax регистр.
in al,60h ; Получаем скэнкод.
mov scancode,al ; Сохраняем скэнкод.
mov ax,ax_
pushf ; Сохраняем флаги.
call old9_hndlr ; Вызываем старое прерывание.
xor ax,ax

continue:

mov al,scancode
cmp al,58h
ja nosound ; Гасит звук при отпускании кнопки.

cmp al, 53 ; диапазон верх
ja exit_9 ; Если >
cmp al, 15 ; диапазон низ
jb exit_9 ; Если <
mov bh,15
jmp sound

sound: mov al, 0B6h ; Инициализация 2го канала
out 43h, al ; микросхемы таймера
mov bl, scancode ; Подготовка частоты
sub bl, bh
mov ax, 200
mul bl
add ax, 348
out 42h, al ; Младший байт в таймер
mov al, ah
out 42h, al ; Старший байт в таймер
in al, 61h ; Читаем данные из 61h порта
or al, 3 ; Установка первых двух битов в 1
out 61h, al ; Включить динамик!
jmp exit_9

nosound: ; Выключить динамик.
in al,61h
and al,252
out 61h,al

exit_9:
mov ax,ax_ ; восстановление ax.
iret
new9_hndlr endp

last_byte db "$" ; метка конца резидентного кода

;*******************************************************************

initialize proc near
assume ds:cseg ;переменные в этом сегменте

mov ax,cs
mov ds,ax

mov ax,3509h ;получаем вектор 9го прерывания
int 21h
mov old9_off,bx ; сохраняем старое смещение
mov old9_seg,es ; сохраняем старый сегмент

mov ax,2509h
mov dx,offset new9_hndlr
int 21h

;Вычисляем необходимую память

mov dx,(offset last_byte - offset cseg + 15)
mov cl,4
shr dx,cl ;конвертируем в параграфы
mov ax,3100h ;TSR
int 21h
initialize endp

cseg ends
end start ;конец!
Автор: akaGM
Дата сообщения: 15.06.2007 15:52

Код:
org 100h

...
mov ax,3100h ;TSR
int 21h
Автор: rain87
Дата сообщения: 15.06.2007 20:40
akaGM
а какая принципиальная разница? 27 тоже проканает, но и 31 сработает
поскольку 31 более продвинутое наверное лучше юзать его
а ком формат удобен тем, что всё в одном сегменте хранится. не надо морочить моск с несколькими резидентными сегментами
yellowair
выглядит вполне красиво. не разбирался особо, как ты делаешь звук и меняешь вектора (я привык менять прямо через память, а не интами, а звук наоборот делать выводом символа 7 на консоль, а не через порты ) - вполне верю, что правильно
если всё это работает - вери гуд
Автор: akaGM
Дата сообщения: 15.06.2007 21:58
rain87

Цитата:
а какая принципиальная разница?

для дос ~2.2-6.22 была, но не помню уже, но была, но не помню...
помню только, что оч строго...


Цитата:
а ком формат удобен тем...

это я ещё помню... все резиденты только в 64к и клал...
а вот _сейчас_? тем же самым удобством и удобен?
кстати, int20 совершенно точно строго для выгрузки кома и ни-ни для MZ...

просто пишут ком, а линковать в него забывают
смотришь -- экзюк, открываешь -- ком
ощущение непорядка для перфекциониста...

ладно, чёрт с ним...
Автор: rain87
Дата сообщения: 15.06.2007 22:49

Цитата:
кстати, int20 совершенно точно строго для выгрузки кома и ни-ни для MZ...
разве? вполне спокойно по инт 20 выходит и из ехе

по крайней мере, если правильно написать ехе - т.е. в начале пуш в стек сегмента ПСП и 0, в конце - дальний рет, то этот рет перейдёт в начало ПСП, где записано инт 20. и ехе вполне благополучно завершается и выгружается из памяти

за линковкой конечно надо следить

Страницы: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384

Предыдущая тема: .NET GUI компоненты


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.