Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RFpro.ru: Ассемблер? Это просто! Учимся программировать


Хостинг портала RFpro.ru:
Московский хостер
Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64

РАССЫЛКИ ПОРТАЛА RFPRO.RU

Лучшие эксперты данной рассылки

Boriss
Статус: Академик
Рейтинг: 2673
∙ повысить рейтинг »
Абаянцев Юрий Леонидович aka Ayl
Статус: Профессионал
Рейтинг: 2279
∙ повысить рейтинг »
vladisslav
Статус: 8-й класс
Рейтинг: 1318
∙ повысить рейтинг »

/ КОМПЬЮТЕРЫ И СОФТ / Программирование / Assembler (Ассемблер)

Номер выпуска:1409
Дата выхода:28.12.2010, 11:00
Администратор рассылки:Лысков Игорь Витальевич (Старший модератор)
Подписчиков / экспертов:222 / 69
Вопросов / ответов:7 / 7

Вопрос № 181570: Здравствуйте, уважаемые эксперты! Прошу помочь с решением несложной задачки: Найти максимальный элемент массива, среди кратных 3 и имеющих четные индексы( среда, ассемблер 16 битный под DOS , tasm и tlink , использовать модель памяти small). Думаю ма...


Вопрос № 181497: Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос: Определить кол-во убывающих последовательностей в массиве из 20 целых неотрицательных элементов. Спасибо!...
Вопрос № 181545: Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос:Подскажите какие-нибудь хороши книжки для изучения ассемблера. ...
Вопрос № 181548: Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос: передо мной поставили задачу, не знаю как ее выполнить: написать загрузчик программ в формате com. основная идея: считать имя файла, открыть файл, определить его размер...
Вопрос № 181550: Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос: ОБЩАЯ ФОРМУЛИРОВКА ЗАДАЧИ для вариантов 1-20. В заданой 16-битной двоичной последовательности выделены 4 группы бит - 3 группы по 5 бит и одна из 1-го бита. ПЕР...
Вопрос № 181559: Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос: Помогите с решением задачи на ассемблере ( среда, ассемблер 16 битный под DOS , tasm и tlink , использовать модель памяти small) :В массиве а (10) первую половину массива о...
Вопрос № 181565: Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос:Помочь с решением задачи на ассемблере ( среда, ассемблер 16 битный под DOS , tasm и tlink , использовать модель памяти small) : Определить количество элементов в каждой убываю...

Вопрос № 181570:

Здравствуйте, уважаемые эксперты! Прошу помочь с решением несложной задачки: Найти максимальный элемент массива, среди кратных 3 и имеющих четные индексы( среда, ассемблер 16 битный под DOS , tasm и tlink , использовать модель памяти small). Думаю массива из 10 символов будет достаточно. Огромная просьба сделать коментарий к каждой строчке, т. к. в ассемблере я полный ноль. Задача должна быть составлена примерно так: ввод массива, поиск элементов с четными индексами и кратными 3, вывод подходящих в другой массив, далее в новом массиве поиск мах, печать исходного массива и мах.

Отправлен: 23.12.2010, 10:50
Вопрос задал: Федоров Иван (Посетитель)
Всего ответов: 1
Страница вопроса »


Отвечает Лысков Игорь Витальевич (Старший модератор) :
Здравствуйте, Федоров Иван !
Программа ждет ровно 10 чисел. Причем можно вводить как в одной строке, так и в нескольких...
Затем выводит введенный массив. Пробегая по четным индексам, проверяет, делится ли нацело на 3.
Ну и ищет среди таких максимальное. Возможен вариант, когда таких чисел может не быть вообще.

Код:
;Найти максимальный элемент массива, среди кратных 3 и имеющих четные индексы
;печать исходного массива и мах

N equ 10 ;размер массива

.model small
.code
start: ;точка входа
mov ax, @data ;загрузим сегментные регистры сегментом данных
mov ds, ax
mov es, ax

call GetArray ;вводим массив
call PrintA rray ;выводим
call SearchMax ;ищем максимум среди кратных 3 и
; имеющих четные индексы (результат в ax)

push ax ;сохраним максимум
lea dx, sMax ;сообщение
mov ah, 9
int 21h
pop ax ;максимум
test ax, ax
jz notFound ;если 0, то максимум не нашли
call PrintNum ;выведем
jmp Exit
notFound:
lea dx, sNotFound ;увы, не было из чего искать
mov ah, 9 ; (например, не было делящихся на 3)
int 21h

Exit:
lea dx, sPress ;выведем приглашение нажать на любую клавишу
mov ah, 9
int 21h

mov ah, 0 ;ждем
int 16h

mov ax, 4c00h
int 21h ;выход в ДОС

GetArray proc ;вводим массив
mov bNum, 80 ;максимальный размер буфера для ввода строки
; (для функции 0ah)
lea dx, sEnter
mov ah, 9
int 21h ;приглашение на ввод элементов массива

lea di, Array ;адрес массива
;посчитаем адрес за массивом (для контроля конца)
mov ax, N ;число элементов
sh l ax, 1 ;по 2 байта (слова)
add ax, di ;добавим адрес начала
mov pLast, ax ;сохраним
GA_ask:
lea dx, bNum
mov ah, 0ah
int 21h ;вводим строку

mov ah, 2
mov dl, 0ah
int 21h ;переход на новую строку

lea si, sBuf ;строка с числами, разделенная разделителями
GA_next:
cmp di, pLast ;массив заполнен?
je GA_ret

call stoi ;[si] -> ax
jcxz GA_ask ;дошли до конца строки - на запрос новой строки
stosw ;сохраняем
jmp GA_next ;на следующее число в строке
GA_ret:
ret
GetArray endp

;функция преобразовывает числовую строку в число
;преобразование заканчивается по любому разделителю или концу строки (0dh)
;признаком конца строки является cx = 0
stoi proc ;преобразование строки [si] в беззнаковое число AX
push dx
xor bx, bx ;здесь будем стоить число
xor cx, cx ;счетчик разрядов
stoi_next:
lodsb ;очередной символ
cmp al, 0dh ;конец стоки?
je stoi_ eol
cmp al, '0'
jb stoi_sep ;любая нецифра - разделитель
cmp al, '9'
ja stoi_sep
push ax ;сохраним новый разряд
mov ax, 10
mul bx ;умножим старшие на 10
pop dx ;новый
and dx, 0fh ;'0'-'9' -> 0-9
add ax, dx ;добавляем новый разряд
mov bx, ax ;сохраняем
inc cx ;считаем
jmp stoi_next ;продолжаем
stoi_sep: ;встретили разделитель
jcxz stoi_next ;были только разделители - на продолжение
; иначе - конец числа и выходим
stoi_eol: ; если числа нет и встретили 0dh - конец строки
mov ax, bx ;число возвращаем в ax
dec si ;шаг назад, чтобы легче было проанализировать 0dh
pop dx
ret
stoi endp

SearchMax proc ;поиск максимума
mov bp, 3 ;будем делить на 3
xor bx, bx ;максимум
mov cx, N/2 ;будем идти только по четным, поэтому половина
xor si, si ;индекс элемента
ArrayLoop:
mov ax, Array[si] ;очередной элемент
mov di, ax ;сохраним
xor dx, dx ;подготавливаемся к делению
div bp ;dx:ax / 3
test dx, dx ;проверяем остаток от деления
jnz Array Next ;не 0 - не нацело - не наше число
cmp bx, di ;делится на 3 - сравниваем с максимальным
jae ArrayNext ;если максим больше - не рассматриваем
mov bx, di ;иначе - новое максимальное
ArrayNext:
add si, 4 ;идем только по четным, нечетные пропускаем
loop ArrayLoop
mov ax, bx ;найденный максимум
ret
SearchMax endp

PrintArray proc ;выводим массив
lea dx, sArray
mov ah, 9
int 21h ;выведем сообщение о массиве

lea si, Array ;адрес массива
mov cx, N ;число элементов
PrintNumLoop:
lodsw ;очередной элемент
call PrintNum ;выводим числовую строку с пробелом в конце
loop PrintNumLoop
ret
PrintArray endp

PrintNum proc ;вывод беззнакового числа из ax
push cx ;сохраним счетчик элементов массива
mov bx, 10 ;будем делить на 10
xor cx, cx ;счетчик цифр
DivLoop:
xor dx, dx ;готовимся к делению dx:ax / bx
div bx ;ax - частное, dx - остаток=очередной младшей цифре
push dx ;сохраним цифру в стеке
inc cx ;посчитаем
test ax, ax ;продолжим, пока не 0
jnz DivLoop
mov ah, 2 ;функция вывода
PrintLoop: ;будем выводить в обратном порядке, начиная со старшей шифры
pop dx ;восстановим очередной разряд
or dl, '0' ;превратим в символ
int 21h ;выведем
loop PrintLoop
mov dl, ' ' ;отделим пробелом
int 21h
pop cx ;восстановим счетчик элементов массива
ret
PrintNum endp

.data
sEnter db 'Enter array (10 numbers): $'
sArray db 'Array: $'
sMax db 0dh,0ah,'Max = $'
sPress db 0dh,0ah,'Press any key$'
sNotFound db 'not found$'

.data?
Array dw N dup (?) ;массив чисел
pLast dw ? ;переменная для контроля адреса элементов массива
;буфер для ввода числовой строки (для функции 0ah)
bNum db ? ;максимальный размер буфера
bCount db ? ;реальный размер строки
sBuf db 80 dup (?) ;сама строка

end start ;точка входа


-----
Люби своего ближнего, как самого себя

Ответ отправил: Лысков Игорь Витальевич (Старший модератор)
Ответ отправлен: 23.12.2010, 23:30
Номер ответа: 265045
Украина, Кировоград
Тел.: +380957525051
ICQ # 234137952
Mail.ru-агент: igorlyskov@mail.ru

Вам помог ответ? Пожалуйста, поблагодарите эксперта за это!
Как сказать этому эксперту "спасибо"?
  • Отправить SMS #thank 265045 на номер 1151 (Россия) | Еще номера »
  • Отправить WebMoney:


  • Вопрос № 181497:

    Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос:
    Определить кол-во убывающих последовательностей в массиве из 20 целых неотрицательных элементов.
    Спасибо!

    Отправлен: 20.12.2010, 20:54
    Вопрос задал: Романенко Татьяна Викторовна (Посетитель)
    Всего ответов: 1
    Страница вопроса »


    Отвечает Лысков Игорь Витальевич (Старший модератор) :
    Здравствуйте, Романенко Татьяна Викторовна!
    Рассматриваем массив из байт, размещенный в сегменте данных
    Если недостаточно комментариев в тексте программы, милости просим в мини-форум

    Код:
    ;Определить кол-во убывающих последовательностей в массиве из 20 целых неотрицательных элементов.

    N equ 20 ;размер массива

    .model small
    .code
    start: ;точка входа
    mov ax, @data ;загрузим сегментные регистры сегментом данных
    mov ds, ax
    mov es, ax

    call GetArray ;вводим массив

    lea si, Array ;адрес массива чисел
    mov cx, N ;количество чисел
    mov bx, 0ffffh ;bx - пре дыдущий элемент, 0ffffh - для первого
    xor dx, dx ;dl - количество убывающих последовательностей
    ;dh - количество в текущей убывающей последовательности
    MainLoop: ;цикл по всем элементам
    lodsw ;очередной
    cmp ax, bx ;сравниваем с предыдущим
    jae tail ;либо закончилась убывающая последовательность, либо не было
    cmp bx, 0ffffh ;для первого
    je new_code ; на сохранение нового предыдущего
    inc dh ;считаем (чтобы знать, что есть убывающая последовательность)
    jmp new_code ;на сохранение нового предыдущего элемента
    tail: ;убывающая последовательность закончилась либо ее не было
    cmp dh, 0 ;если последовательности не было
    je new_code ;то на сохранение нового предыдущего элемента
    ;убывающая последовательность закончилась
    inc dl ;считаем убывающие последовательности
    mov dh, 0 ;сбросим длину
    new_code:
    mov bx, ax ;сохраним новый предыдущий элемент
    loop MainLoop ;по всем элементам массива

    cmp dh, 0 ;закончилось на убывающей последовательности?
    je CmpCount ;нет, идем дальше
    inc dl ;учтем ее
    CmpCount:
    cmp dl, 0 ;проверим, а были ли вообще убывающие последовательности
    jne found ;были
    lea dx, sNotFound ;сообщение, что не были
    mov ah, 9
    int 21h
    jmp exit ;на выход
    found: ;вывод на экран
    push dx
    lea dx, sFound
    mov ah, 9
    int 21h
    pop dx

    mov al, dl ;число убывающих последовательностей
    call PrByte
    exit: ;выход
    lea dx, sAny
    mov ah, 9
    int 21h ;any key

    mov ah, 8
    int 21h ;ждем any key

    mov ax, 4c00h
    int 21h ;выход в ДОС

    PrByte proc ;вывод байта, как числовой строки
    mov bl, 10 ;будем делить на 10
    xor cx, cx ;счетчик цифр
    divLoop:
    mov ah, 0 ;подготавливаемся к делению
    div bl ;ax / 10
    push ax ;сохраним ah - остаток - очередную цмладшую цифру
    inc cx ;ситаем
    cmp al, 0 ;еще есть десятичные разряды?
    jne divLoopprLoop: ;выведем в обратном порядке
    pop ax ;извлечем цифру в ah
    mov dl, ah ;для функции 2
    or dl, '0' ;0-9 -> '0'-'9'
    mov ah, 2
    int 21h ;выведем
    loop prLoop ;по всем цифрам
    ret
    PrByte endp

    GetArray proc ;вводим массив
    mov bNum, 80 ;максимальный размер буфера для ввода строки
    ; (для функции 0ah)
    lea dx, sEnter
    mov ah, 9
    int 21h ;приглашение на ввод элементов массива

    lea di, Array ;адрес массива
    ;посчитаем адрес за массивом (для контроля конца)
    mov ax, N ;число элементов
    shl ax, 1 ;по 2 байта (слова)
    add ax, di ;добавим адрес начала
    mov pLast, ax ;сохраним
    GA_ask:
    lea dx, bNum
    mov ah, 0ah
    int 21h ;вводим строку

    mov ah, 2
    mov dl, 0ah
    int 21h ;переход на новую строку

    lea si, sBuf ;строка с числами, разделенная разделителями
    GA_next:
    cmp di, pLast ;массив заполнен?
    je GA_ret

    call stoi ;[s i] -> ax
    jcxz GA_ask ;дошли до конца строки - на запрос новой строки
    stosw ;сохраняем
    jmp GA_next ;на следующее число в строке
    GA_ret:
    ret
    GetArray endp

    ;функция преобразовывает числовую строку в число
    ;преобразование заканчивается по любому разделителю или концу строки (0dh)
    ;признаком конца строки является cx = 0
    stoi proc ;преобразование строки [si] в беззнаковое число AX
    push dx
    xor bx, bx ;здесь будем стоить число
    xor cx, cx ;счетчик разрядов
    stoi_next:
    lodsb ;очередной символ
    cmp al, 0dh ;конец стоки?
    je stoi_eol
    cmp al, '0'
    jb stoi_sep ;любая нецифра - разделитель
    cmp al, '9'
    ja stoi_sep
    push ax ;сохраним новый разряд
    mov ax, 10
    mul bx ;умножим старшие на 10
    pop dx ;новый
    and dx, 0fh ;'0'-'9' -> 0-9
    add ax, dx ;добавляем новый разряд
    mov bx, ax ;сохраняем
    inc cx ;считаем
    jmp stoi_next ;продолжаем
    stoi_sep: ;встретили разделитель
    jcxz stoi_next ;были только разделители - на продолжение
    ; иначе - конец числа и выходим
    stoi_eol: ; если числа нет и встретили 0dh - конец строки
    mov ax, bx ;число возвращаем в ax
    dec si ;шаг назад, чтобы легче было проанализировать 0dh
    pop dx
    ret
    stoi endp

    .data
    sEnter db 'Enter array (20 numbers): $'
    sNotFound db 'Not found$'
    sFound db 'Found: count = $'
    sAny db 0dh,0ah,'Press any key$'
    .data?
    Array dw N dup (?) ;массив чисел
    pLast dw ? ;переменная для контроля адреса элементов массива
    ;буфер для ввода числовой строки (для функции 0ah)
    bNum db ? ;максимальный размер буфера
    bCount db ? ;реальный размер строки
    sBuf db 80 dup (?) ;сама строка

    end start

    -----
    Люби своего ближнего, как самого себя

    Ответ отправил: Лысков Игорь Витальевич (Старший модератор)
    Ответ отправлен: 21.12.2010, 11:43
    Номер ответа: 264963
    Украина, Кировоград
    Тел.: +380957525051
    ICQ # 234137952
    Mail.ru-агент: igorlyskov@mail.ru

    Вам помог ответ? Пожалуйста, поблагодарите эксперта за это!
    Как сказать этому эксперту "спасибо"?
  • Отправить SMS #thank 264963 на номер 1151 (Россия) | Еще номера »
  • Отправить WebMoney:


  • Вопрос № 181545:

    Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос:Подскажите какие-нибудь хороши книжки для изучения ассемблера.

    Отправлен: 22.12.2010, 14:13
    Вопрос задал: Magma (Посетитель)
    Всего ответов: 1
    Страница вопроса »


    Отвечает Павел Юрьевич (7-й класс) :
    Здравствуйте, Magma!

    Если для начинающих, то:
    - Ассемблер для процессоров Intel Pentium - Магда С.Ю.

    А вообще вот:
    - Assembler - Учебный курс - Пирогов В.Ю.
    - Assembler для DOS, Windows и UNIX - Зубков С.В.
    - Assembler. Учебник для вузов - Юров В.и.
    - Assembler. Практикум - Юров В.И.
    - Архитектура IBM PC и язык Ассемблера - Митницкий В.Я.
    - Ассемблер в задачах защиты информации - Абашев А.А. ....
    - Ассемблер для Windows - Пирогов В.Ю.
    - Ассемблер и дизассемблирование - Пирогов В.Ю.
    - Ассемблер и программирование для IBM PC - Абель Питер
    - Ассемблер. Разработка и оптимизация Windows-приложений - Магда Ю.С.
    - Изучаем ассемблер - Крупник А.Б.
    - Искусство программирования на Ассемблере. Лекции и упражнения - Голубь Н.Г.
    - Персональные ЭВМ IBM PC и XT.Программирование на языке ассемблера - Скэнлон Л.
    - Программирование аппаратных средств в Windows - Несвижский В.
    - Программирование на аппаратном уровн е. Специальный справочник - Кулаков В.
    - Программирование на языке ассемблера для микроконтроллеров семейства i8051 - Каспер Эрни
    - Программирование на языке ассемблера для микропроцессоров 8080 и 8085 - Л. Левенталь
    - Системное программирование на персональном компьютере - Фельдман С.К.
    - Язык ассемблера для процессоров Intel - Ирвин, Кип
    - Язык ассемблера: уроки программирования - Рудаков П.И

    Все есть в электронном виде. Если нужны ссылки для скачивания, пишите в почту.

    Ответ отправил: Павел Юрьевич (7-й класс)
    Ответ отправлен: 22.12.2010, 14:19
    Номер ответа: 265000

    Вам помог ответ? Пожалуйста, поблагодарите эксперта за это!
    Как сказать этому эксперту "спасибо"?
  • Отправить SMS #thank 265000 на номер 1151 (Россия) | Еще номера »
  • Отправить WebMoney:


  • Вопрос № 181548:

    Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос:
    передо мной поставили задачу, не знаю как ее выполнить: написать загрузчик программ в формате com. основная идея:
    считать имя файла, открыть файл, определить его размер, закрыть файл, выделить под него буфер, записать его в буфер и передать ему управление. Язык Tasm, модель процессора-8086, под MS-Dos; Заранее благодарен!;

    Отправлен: 22.12.2010, 15:25
    Вопрос задал: vito007 (1-й класс)
    Всего ответов: 1
    Страница вопроса »


    Отвечает Лысков Игорь Витальевич (Старший модератор) :
    Здравствуйте, vito007!
    Вот Вам загрузчик, который грузит одну программу и завершается после ее завершения.
    Для нормальной работы надо использовать функцию 4bh, но Вам больше и не требуется
    Будут вопросы - обращайтесь в мини-форум
    Код:
    cseg segment para 'code'
    assume cs:cseg,ds:cseg,es:cseg,ss:cseg
    ;----------------------------------------------
    .286
    org 100h
    start:
    ;разместим 100h стека сразу за программой
    lea ax, last ;последний адрес
    and ax, 0fffeh ;кратно 2
    add ax, 100h ;размер 100h
    mov s p, ax

    call GetMem ;освободим лишнюю память,
    jnc main ;выделим память до конца для загрузки программы

    mov al, 1 ;ошибка памяти (можно вывести сообщение)
    jmp finish

    main:
    lea dx, prompt ;приглашение на ввод имени программы
    mov ah, 9
    int 21h

    lea dx, sBuf
    mov ah, 0ah
    int 21h ;вводим

    call Parse ;разбираем строку
    jc main ;если ошибка, то на повтор

    call CmpExit ;сравним на строку 'exit'
    je exit ;просто уходим

    call ReadFile ;читаем файл с именем в ax в выделенный блок памяти
    jnc GotoProgramm ;если файл прочитан - идем дальше
    mov ah, 9 ;иначе выводим ошибку и на повтор ввода
    int 21h
    jmp main
    GotoProgramm:
    mov ah, 2 ;перевод строки
    mov dl, 0dh
    int 21h
    mov dl, 0ah
    int 21h

    xor si, si ;зададим адрес возврата в PSP
    mov word ptr [si+0ah], offset return
    mov word ptr [si+0ch], cs

    mov sp_save, sp ;сохраним вершину стека

    mov ax, segnew ;настроим сегментные регистры для загруженной программы
    mov ds, ax
    mov es, ax
    cli
    mov ss, ax ;стек
    xor sp, sp
    sti

    jmp dword ptr cs:point ;длинный переход на программу

    return: ;точка возврата
    mov ax, cs ;настраиваемся на свои сегментные регистры
    mov ds, ax
    mov es, ax
    cli
    mov ss, ax
    mov sp, sp_save ;стек
    sti

    lea dx, sAny
    mov ah, 9
    int 21h

    mov ah, 1 ;ждем any key
    int 21h
    exit:
    mov al, 0
    finish:
    mov ah, 4ch ;выход в ДОС
    int 21h

    Parse proc ;разбор строки
    push es
    mov es, segnew ;сегмент PSP новой программы
    lea si, sCom
    mov di, 81h ;адрес строки параметров
    xor cx, cx ;счетчик строки параметров
    ParseStart:
    lodsb ;очередной символ
    cmp al, 0dh
    je ParseErr ;дошли до конца, не нашли ничего, кроме пробелов...
    cmp al, ' '
    je ParseStart ;лидирующие пробелы п ропускаем
    lea dx, -1[si] ;запомним начало имени программы
    ParseEnd: ;ищем конец имени программы
    lodsb
    cmp al, 0dh
    je SetNameEnd ;дошли до конца строки
    cmp al, ' '
    jne ParseEnd ;дошли до разделительного пробела?
    SetNameEnd:
    mov byte ptr [si-1], 0 ;закрываем строку имени нулем
    CopyParm:
    stosb ;код копируем в PSP новой программы
    cmp al, 0dh ;дошли до конца?
    je SetParmLen ;да - вставляем длину строки
    inc cx ;считаем
    lodsb ;читаем следующий
    jmp CopyParm ;пока не дойдем до конца строки
    SetParmLen:
    mov di, 80h ;адрес длины строки параметров в PSP
    mov es:[di], cl ;запишем
    mov ax, dx ;адрес имени программы
    clc ;признак, что все ок
    ParseRet:
    pop es
    ret
    ParseErr:
    stc ;признак ошибки
    jmp ParseRet
    Parse endp

    ReadFile proc ;читаем файл
    push ds
    mov dx, ax ;адрес имени
    mov ax, 3d00h ;открваем
    int 21h
    jc OpenError ;не о ткрывается!
    mov bx, ax ;handle
    mov ds, segnew ;сегмент новой программы
    mov dx, 100h ;смещение
    mov cx, 0ff00h ;максиму м 64k-100h
    mov ah, 3fh ;читаем
    int 21h
    jc ReadError ;ошибка чтения
    mov ah, 3eh ;закрываем
    int 21h
    clc ;все ок
    ReadFileRet:
    pop ds
    ret
    OpenError:
    lea dx, sOpenError
    stc
    jmp ReadFileRet
    ReadError:
    lea dx, sReadError
    stc
    jmp ReadFileRet
    ReadFile endp

    CmpExit proc ;сравнение на строку 'exit',
    push ax ;причем регистр не учитываем
    lea si, sExit ;адрес строки exit
    mov di, ax ;адрес команды
    mov cx, lenExit ;длина строки вместе с завершающим 0
    CmpLoop:
    lodsb
    xor al, [di] ;если равно, то результат либо 0, либо 20h
    jz CmpNext
    cmp al, 20h ;большие и малые отличаются на 20h
    jnz CmpExitRet ;FZ=0 - не равно
    CmpNext:
    inc di ;по всем
    loop CmpLoop
    xor al, al ;чтобы FZ=1 - признак равенства
    CmpExitRet:
    pop ax
    ret
    CmpExit endp

    GetMem proc ;разберемся с памятью, на входе ax - вершина стека
    add ax, 0fh ;выр авниваем на границу параграфа
    shr ax, 4 ;ближайший сверху
    mov bx, ax ;длина программы в параграфах
    mov ah, 4ah
    int 21h ;усекаем свою память

    mov ah, 48h ;запросим до конца доступной
    mov bx, 0a000h ;максимум
    int 21h ;столько не даст, но мы узнаем, сколько есть :)

    mov ah, 48h ;в bx вернулось, сколько можно запросить
    int 21h ;вот ее и выделяем
    jc GMRet ;если сейчас ошибка, то извините...
    mov segnew, ax ;сохраняем сегмент
    mov dx, ax
    mov AH, 26h ;строим там PSP для новой программы
    int 21h
    GMRet:
    ret
    GetMem endp
    ;--------------------------------------
    sp_save dw 0 ;для сохранения SP
    point dw 100h ;длинный указатель на новую программу
    segnew dw 0
    prompt db 0dh,0ah,'> $' ;подсказка
    sBuf db 80 ;буфер для ввода строки с консоли
    count db 0
    sCom db 80 dup (0)

    sExit db 'exit',0 ;строка для выхода
    lenExit equ $-sExit ;длина
    sOpe nError db 0dh,0ah,'File open error$'
    sReadError db 0dh,0ah,'File read error$'
    sAny db 0dh,0ah,'Press any key$'
    ;--------------------------------------
    last label byte ;последний адрес программы
    ;за ним разместим стек
    cseg ends

    end start

    -----
    Люби своего ближнего, как самого себя

    Ответ отправил: Лысков Игорь Витальевич (Старший модератор)
    Ответ отправлен: 23.12.2010, 12:09
    Номер ответа: 265028
    Украина, Кировоград
    Тел.: +380957525051
    ICQ # 234137952
    Mail.ru-агент: igorlyskov@mail.ru

    Оценка ответа: 3

    Вам помог ответ? Пожалуйста, поблагодарите эксперта за это!
    Как сказать этому эксперту "спасибо"?
  • Отправить SMS #thank 265028 на номер 1151 (Россия) | Еще номера »
  • Отправить WebMoney:


  • Вопрос № 181550:

    Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос:

    ОБЩАЯ ФОРМУЛИРОВКА ЗАДАЧИ для вариантов 1-20. В заданой 16-битной
    двоичной последовательности выделены 4 группы бит - 3 группы по 5 бит
    и одна из 1-го бита.
    ПЕРЕСТАВИТЬ 5-битные группы в соответствии с заданным вариантом.
    Положение группы из 1-го бита задается вариантом и при перестановках
    5-битных групп остается неизменным. В каждом варианте указан номер рисунка
    с распределением групп и требуемый порядок групп после их перестаноки.

    16 разрядная последоватнльность
    xххххххххххххххx
    ?-----*****.....
    4 1гр. 2гр. 3 гр.
    после перестановки:
    2 1 3

    Основная программа в паскале, обработка - в файле .obj. Процессор 286й.
    Переставлять группы надо в числе введенном с клавиатуры в десятичной форме.
    Заранее большое спасибо.

    Отправлен: 22.12.2010, 17:40
    Вопрос задал: Посетитель - 354017 (Посетитель)
    Всего ответов: 1
    Страница вопроса »


    Отвечает Лысков Игорь Витальевич (Старший модератор) :
    Здравствуйте, Посетитель - 354017!
    С Паскалем надеюсь справитесь самостоятельно.
    chbits.asm
    Код:

    ; Подключение {$L chbits} { подключение файла chbits.obj }
    ; Описание function ChBits(:integer):integer;external;
    ; Вызов i:=ChBits(i);
    ; Функция меняем местами группы бит 1 и 2
    ; ?-----*****.....
    ; 4 1 2 3
    .model large,pascal
    .code
    .286
    public ChBits
    ChBits proc near n:word ;параметр - слово
    mov ax, n ;читаем слово
    mov cx, ax ;сохраняем в cx
    and cx, 1000000000011111b ;оставляем неизменные биты
    mov dx, ax ;сохраним в рабочем регистре
    and dx, 0000 001111100000b ;оставим только группу 2
    shl dx, 5 ;сдвинем влево группу 2
    and ax, 0111110000000000b ;оставим только группу 1
    shr ax, 5 ;сдвинем вправо группу 1
    or ax, dx ;объединим 1 и 2
    or ax, cx ;объединяем с неизменными битами
    ret ;результат в ax
    endp
    end

    -----
    Люби своего ближнего, как самого себя

    Ответ отправил: Лысков Игорь Витальевич (Старший модератор)
    Ответ отправлен: 23.12.2010, 16:03
    Номер ответа: 265030
    Украина, Кировоград
    Тел.: +380957525051
    ICQ # 234137952
    Mail.ru-агент: igorlyskov@mail.ru

    Вам помог ответ? Пожалуйста, поблагодарите эксперта за это!
    Как сказать этому эксперту "спасибо"?
  • Отправить SMS #thank 265030 на номер 1151 (Россия) | Еще номера »
  • Отправить WebMoney:


  • Вопрос № 181559:

    Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос:
    Помогите с решением задачи на ассемблере ( среда, ассемблер 16 битный под DOS , tasm и tlink , использовать модель памяти small) :В массиве а (10) первую половину массива отсортировать по убыванию, вторую по возрастанию. Массив вводим с консоли, вывод на экран делаем
    прошу сделать как можно проще и желательно описание к каждой строчке чтобы было как можно понятнее
    заранее благодарен
    Вот пример одной из програмы в данной среде:

    Код:
    .model small
    .stack 48
    .data
    string db 10 dup (?),'$'
    chet db 5 dup (?)
    nech db 5 dup (?)
    ic db 0
    it db 0
    .code
    mov ax,@data
    mov ds,dx
    mov es,ax
    mov ss,ax
    lea di,string
    mov cl,10
    mov ah,1
    c1: int 21h
    and al,ofh
    sosb
    loop c1
    mov bl,2
    mov bh,3
    lea si,string
    lea di,chet
    lea bp,nech
    mov cl,10
    mov dh,0
    c2: xor ax,ax
    lodsb
    mov dl,al
    div bl
    cmp ah,0
    je cd
    xor ax,ax
    mov al,dl
    div bh
    cmp ah,0
    je nd
    jmp cc
    cd: xor ax,ax
    mov al,dh
    div bl
    cmp ah,0
    jne c06
    mov al,dl
    or al,30h
    stosb
    inc ic
    jmp cc
    c06: cmp dl,0
    je n06
    cmp dl,6
    je n06
    cmp cc
    nd: xor ax,ax
    mov al,dh
    div bl
    cmp ah,0
    je cc
    n06: or dl,30h
    mov [bp],dl
    inc bp
    inc it
    cc: inc dh
    loop c2
    mov cl,ic
    lea si,chet
    lea di,string
    re p movsb
    mov cl,it
    lea si,nech
    rep movsb
    mov al,'$'
    mov ah,'^'
    sc: scasb
    jz vyvod
    dec di
    mov [di],ah
    inc di
    jmp sc
    vyvod: mov dl,10
    mov ah,2
    int 21h
    lea dx,string
    mov ah,9
    int 21h
    mov ah,4ch
    int 21h
    end

    Отправлен: 22.12.2010, 20:12
    Вопрос задал: Игорь Викторович (Посетитель)
    Всего ответов: 1
    Страница вопроса »


    Отвечает Зенченко Константин Николаевич (Модератор) :
    Здравствуйте, Игорь Викторович!

    Смотрите приложение.
    В программе использована только одна общая подпрограмма сортировки и базово-индексная адресация.
    Перед каждым вызовом подпрограммы устанавливаются начальные значения(базы и индекса) и направление сортировки.
    Программа проверяелась в TASM 4.1
    Вопросы задавайте в мини-форуме.
    Удачи!

    Приложение:

    -----
    Итерация от человека. Рекурсия — от Бога. — Л. Питер Дойч

    Ответ отправил: Зенченко Константин Николаевич (Модератор)
    Ответ отправлен: 23.12.2010, 13:45
    Номер ответа: 265029
    Украина, Киев
    Тел.: +38-097-238-60-03
    Адрес: Украина, Киев

    Вам помог ответ? Пожалуйста, поблагодарите эксперта за это!
    Как сказать этому эксперту "спасибо"?
  • Отправить SMS #thank 265029 на номер 1151 (Россия) | Еще номера »
  • Отправить WebMoney:


  • Вопрос № 181565:

    Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос:Помочь с решением задачи на ассемблере ( среда, ассемблер 16 битный под DOS , tasm и tlink , использовать модель памяти small) : Определить количество элементов в каждой убывающей последовательности массива а(20). Найти максимальный из них.
    Просьба написать пояснение к операторам в программе .
    Вот пример одной из програмы в данной среде.

    Код:
    .model small
    .stack 48
    .data
    string db 10 dup (?),'$'
    chet db 5 dup (?)
    nech db 5 dup (?)
    ic db 0
    it db 0
    .code
    mov ax,@data
    mov ds,dx
    mov es,ax
    mov ss,ax
    lea di,string
    mov cl,10
    mov ah,1
    c1: int 21h
    and al,ofh
    sosb
    loop c1
    mov bl,2
    mov bh,3
    lea si,string
    lea di,chet
    lea bp,nech
    mov cl,10
    mov dh,0
    c2: xor ax,ax
    lodsb
    mov dl,al
    div bl
    cmp ah,0
    je cd
    xor ax,ax
    mov al,dl
    div bh
    cmp ah,0
    je nd
    jmp cc
    cd: xor ax,ax
    mov al,dh
    div bl
    cmp ah,0
    jne c06
    mov al,dl
    or al,30h
    stosb
    inc ic
    jmp cc
    c06: cmp dl,0
    je n06
    cmp dl,6
    je n06
    cmp cc
    nd: xor ax,ax
    mov al,dh
    div bl
    cmp ah,0
    je cc
    n06: or dl,30h
    mov [bp],dl
    inc bp
    inc it
    cc: inc dh
    loop c2
    mov cl,ic
    lea si,chet
    lea di,string
    rep movsb
    mov cl,it
    lea si,nech
    rep movsb
    mov al,'$& #39;
    mov ah,'^'
    sc: scasb
    jz vyvod
    dec di
    mov [di],ah
    inc di
    jmp sc
    vyvod: mov dl,10
    mov ah,2
    int 21h
    lea dx,string
    mov ah,9
    int 21h
    mov ah,4ch
    int 21h
    end

    Отправлен: 23.12.2010, 00:15
    Вопрос задал: кирюша (Посетитель)
    Всего ответов: 1
    Страница вопроса »


    Отвечает Лысков Игорь Витальевич (Старший модератор) :
    Здравствуйте, кирюша!
    Посчитал неудобным ограничивать ввод ровно 20 символами.
    Можно вводить любое число (0-79) символов.
    Кроме того, для наглядности вывожу все найденные убывающие последовательности вместе с количеством
    Если что непонятно, обращайтесь в мини-форум
    Код:
    ;Определить количество элементов в каждой убывающей последовательности массива а(20). 
    ;Найти максимальный из них.
    .model small
    .code
    start:
    mov ax, @data
    mov ds, ax
    mov es, ax

    lea dx, sEnter
    mov ah, 9
    int 21h ;приглашение ввести строку

    mov bMax, 80 ;максимальная длина
    lea dx, bMax
    mov ah, 0ah
    int 21h ;вводим строку

    lea dx, sRings ;выведем сообщение о выводе периодов убывания
    mov ah, 9
    int 21h

    xor cx, cx
    mov cl, bCount ;длина строки
    jcxz PrNotFound ;пустая строка

    xor si, si ;индекс в введенной строке
    mov dh, 00h ;dh - максимальное количество
    mov bx, 0000h ;bh - текущее число убываний
    ;bl - предыдущий элемент
    mov ah, 0 ;ah - число периодов убывания
    MainLoop: ;цикл по всем элементам
    mov al, sBuf[si] ;очередной
    cmp al, bl ;сравниваем с предыдущим
    jae endInc ;>= - убыв последовательность закончилась либо ее не было
    ;идет убыв последовательность
    cmp bl, 0 ;для первого элемента
    je SetStart ;просто сохраняем начало последовательности и новый предыдущий элемент
    inc bh ;для всех последующих - считаем
    jmp new_code ;на сохранение нового предыдущего элемента
    endInc: ;убыв последовательность закончилась либо ее не было
    cmp bh, 0 ;если по следовательности не было
    je SetStart ;сохраняем начало последовательности и новый предыдущий элемент
    inc ah ;была - считаем
    cmp bh, dh ;сравниваем с максимальным количеством
    jbe OutChain
    mov dh, bh ;сохраним новое максим
    OutChain:
    call PrChain ;выводим текущую последовательность, начиная с [di] и длиной bh
    mov bh, 0 ;обнулим текущее количество
    SetStart:
    mov di, si ;адрес начала последовательности
    new_code:
    mov bl, al ;сохраним новый предыдущий элемент
    inc si ;на следующий элемент
    loop MainLoop ;по всем элементам массива

    ;проверим последнюю последовательность
    cmp bh, 0 ;было ли что-то убывающее?
    je cmpChain ;не было, на проверку, было ли вообще
    inc ah ;считаем
    cmp bh, dh ;ну и сравним с максимальным
    jbe OutLastChain
    mov dh, bh ;новое максим
    OutLastChain:
    call PrChain ;выводим последнюю убыв последовательность
    jmp PrMax ;на вывод максимального элемента

    cmpCha in:
    cmp ah, 0 ;проверим, а были ли вообще возраст последовательности
    jne PrMax ;были - на вывод макс
    PrNotFound:
    lea dx, sNotFound ;сообщение, что не были
    mov ah, 9
    int 21h
    jmp Exit ;на выход

    PrMax: ;вывод на экран статистики
    push dx ax ;сохраним
    lea dx, sTotal
    mov ah, 9
    int 21h ;'Total: '
    pop ax ;восстановим число последовательностей
    mov al, ah ;число последовательностей
    call PrByte ;выведем число
    lea dx, sMax
    mov ah, 9
    int 21h ;'max count:'
    pop dx ;восстановим максим количество
    mov al, dh ;максимальное количество в цепочке -1 !
    inc al ;учтем первый, который не считался
    call PrByte ;выведем число
    Exit: ;выход
    lea dx, sAny
    mov ah, 9
    int 21h ;any key

    mov ah, 8
    int 21h ;ждем any key

    mov ax, 4c00h
    int 21h ;выход в ДОС

    PrChain proc ;вывод последовательности, начиная с [di] и длиной bh
    push ax dx
    inc bh ;добавим самый первый, который не считался
    push bx ;сохраним для вывода
    ChainPrint:
    mov dl, sBuf[di] ;элемент
    inc di ;на след
    mov ah, 2
    int 21h ;выведем символ
    dec bh ;счетчик - 1
    jnz ChainPrint ;по всем

    lea dx, sCount ;добавим длину цепочки
    mov ah, 9
    int 21h
    pop bx ;длина цепочки
    mov al, bh
    call PrByte
    mov dl, 0dh ;перевод строки
    int 21h
    mov dl, 0ah
    int 21h
    pop dx ax
    ret
    PrChain endp

    PrByte proc ;вывод байта, как числовой строки
    push bx cx
    mov bl, 10 ;будем делить на 10
    xor cx, cx ;счетчик цифр
    divLoop:
    mov ah, 0 ;подготавливаемся к делению
    div bl ;ax / 10
    push ax ;сохраним ah - остаток - очередную цмладшую цифру
    inc cx ;ситаем
    cmp al, 0 ;еще есть десятичные разряды?
    jne divLoop
    prLoop: ;выведем в обратном порядке
    pop ax ;извлечем цифру в ah
    mov dl, ah ;для функции 2
    or dl, '0' ;0-9 -> '0'-'9'
    mov ah, 2
    int 21h ;выведем
    loop prLoop ;по всем цифрам
    pop cx bx
    ret
    PrByte endp

    .dat a
    sEnter db 'Enter string: $'
    sRings db 0ah,0ah,'Rings:',0dh,0ah,'$'
    sNotFound db 'Rings not found!',0dh,0ah,'$'
    sCount db ', count: $'
    sTotal db 0ah,'Total: $'
    sMax db ', maximal count: $'
    sAny db 0dh,0ah, 'Press any key$'

    .data?
    ;буфер для ввода числовой строки (для функции 0ah)
    bMax db ? ;максимальный размер буфера
    bCount db ? ;реальный размер строки
    sBuf db 80 dup (?) ;сама строка

    end start

    -----
    Люби своего ближнего, как самого себя

    Ответ отправил: Лысков Игорь Витальевич (Старший модератор)
    Ответ отправлен: 24.12.2010, 13:18
    Номер ответа: 265051
    Украина, Кировоград
    Тел.: +380957525051
    ICQ # 234137952
    Mail.ru-агент: igorlyskov@mail.ru

    Вам помог ответ? Пожалуйста, поблагодарите эксперта за это!
    Как сказать этому эксперту "спасибо"?
  • Отправить SMS #thank 265051 на номер 1151 (Россия) | Еще номера »
  • Отправить WebMoney:


  • Оценить выпуск »
    Нам очень важно Ваше мнение об этом выпуске рассылки!

    Задать вопрос экспертам этой рассылки »

    Скажите "спасибо" эксперту, который помог Вам!

    Отправьте СМС-сообщение с тестом #thank НОМЕР_ОТВЕТА
    на короткий номер 1151 (Россия)

    Номер ответа и конкретный текст СМС указан внизу каждого ответа.

    Полный список номеров »

    * Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи. (полный список тарифов)
    ** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
    *** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.


    © 2001-2010, Портал RFPRO.RU, Россия
    Авторское право: ООО "Мастер-Эксперт Про"
    Автор: Калашников О.А. | Программирование: Гладенюк А.Г.
    Хостинг: Компания "Московский хостер"
    Версия системы: 2010.6.25 от 13.12.2010

    В избранное