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

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


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

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

Чемпионы рейтинга экспертов в этой рассылке

Boriss
Статус: Академик
Рейтинг: 2375
∙ повысить рейтинг »
_Ayl_
Статус: Профессионал
Рейтинг: 1849
∙ повысить рейтинг »
vladisslav
Статус: 6-й класс
Рейтинг: 1227
∙ повысить рейтинг »

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

Номер выпуска:1344
Дата выхода:26.05.2010, 22:00
Администратор рассылки:Лысков Игорь Витальевич, Модератор
Подписчиков / экспертов:264 / 63
Вопросов / ответов:6 / 6
IRC-канал по теме:#assembler

Вопрос № 178539: Здравствуйте, господа эксперты! Помогите, пожалуйста, решить следующую задачу на ассемблере для 8051(MCS 51). Наверняка уже давно есть готовые решения, но с наскока ничего вменяемого в интернете я не нашел.. Необходимо взять 16-ти битное число, хр...


Вопрос № 178548: Здравствуйте уважаемые эксперты! Недавно нашел в сети код будильника, работает прекрасно. Чисто для себя хочу разобраться как он работает. Если есть возможность прокомментируйте пожалуйста, т.к не все понятно(что не ясно отметил знаками вопроса). Вопрос № 178549: Уважаемые эксперты! Требуется написать программу(с комментариями) Ввести с клавиатуры две строки. Определить, равны ли они. Ввод строк с клавиатуры и команды пакетной обработки (строковые команды) в языке Assebmler. С клавиатуры вводятся только симво...
Вопрос № 178550: Уважаемые эксперты! Требуется написать программу(с комментариями) Вывести на экран таблицу символов ASCII, используя для вывода символов различные атрибуты цвета и фона. Вывод на экран в текстовом режиме с использованием средств DOS и BIOS. Бонусн...
Вопрос № 178551: Уважаемые эксперты! Требуется написать программу(с комментариями) Ввести с клавиатуры имя каталога и маску файлов. Перенести все соответствующие маске файлы в каталог уровнем выше указанного. Если указанный каталог остался пуст – удалить его. Работа...
Вопрос № 178552: Уважаемые эксперты! Требуется написать программу(с комментариями) Даны три стороны треугольника. Найти радиус описанной окружности. Операции с плавающей точкой в архитектуре x86 Платформа DOS, ассемблер TASM....

Вопрос № 178539:

Здравствуйте, господа эксперты!
Помогите, пожалуйста, решить следующую задачу на ассемблере для 8051(MCS 51). Наверняка уже давно есть готовые решения, но с наскока ничего вменяемого в интернете я не нашел.. Необходимо взять 16-ти битное число, хранящееся в двух 8-ми битных регистрах, и представить его в двоично-десятичном виде методом двух счетчиков. Иными словами, у меня было число 1234, а получить мне нужно четыре цифры (1,2,3,4). Основная проблема в том, что АЛУ восьмибитное, сам алгоритм перевода мне известен.

Отправлен: 21.05.2010, 14:01
Вопрос задал: airens, Студент
Всего ответов: 1
Страница вопроса »


Отвечает Лысков Игорь Витальевич, Модератор :
Здравствуйте, airens.
Вот Вам подпрограмма для преобразования. Данная задача решается предварительным подсчетом сотен путем отнимания числа 100.
Выводится младшим вперед, несложно переделать, если надо наоборот.
Удачи!
Код:
;r2 = low
;r3 = high
;r0 = адрес BCD, младший первым
WordToBCD:
mov r4,#0 ;сотни
mov a,r2 ;младший байт числа
CalcHundreds: ;цикл подсчета сотен
clr C ;сбросим C для вычитания
subb a,#100 ;отнимаем 100
xch a,r3 ;acc=старый старший байт, r3=мл-100=новый младший
subb a,#0 ;учтем перенос
xch a,r3 ;r3=новый старший, acc=новый младший
jc FormBCD ;если был заем, значит число меньше сотни
inc r4 ;иначе больше и мы добавляем очередную сотню
jmp CalcHundreds ;проверяем дальше
FormBCD: ;имеем в acc две младшие десятичные цифры, а в r4 - две старшие
add a,#100 ;был заем, число отрицательное, добавим 100, чтобы вернуть значение
call FormTwoBCD ;преобразуем!
mov a,r4 ;две старшие цифры
FormTwoBCD: ;преобразуем число < 100 в две десятичные цифры
mov b,#10 ;будем делить на 10
div ab ;a=частное, b=остаток
mov @r0,b ;младший вперед
inc r0
mov @r0,a ;старшая цифра
inc r0
ret
end

-----
Удачи!

Ответ отправил: Лысков Игорь Витальевич, Модератор
Ответ отправлен: 22.05.2010, 09:46
Номер ответа: 261564
Украина, Кировоград
Тел.: +380957525051
ICQ # 234137952
Mail.ru-агент: igorlyskov@mail.ru
Абонент Skype: igorlyskov

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

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

  • Вопрос № 178548:

    Здравствуйте уважаемые эксперты! Недавно нашел в сети код будильника, работает прекрасно. Чисто для себя хочу разобраться как он работает. Если есть возможность прокомментируйте пожалуйста, т.к не все понятно(что не ясно отметил знаками вопроса). Здесь готовый файл .com.

    Код:

    .286
    .model tiny

    BEEP_DUR_INNER = 5000 ;???
    BEEP_DUR_OUTTER = 0D000h ;???

    BEEP_TONE = 5 ;???

    MAX_HR = 24 ;максимально часов
    MAX_MS = 60 ;максимально минут
    .code
    org 100h
    begin:
    jmp start

    old_int_2fh dd ?

    hrs dB ? ;часы
    min dB ? ;минуты
    sec dB ? ;секунды

    int_4a_code:
    in al,61h ;???
    push ax
    or al,03h ;???
    out 61h,al ;???


    mov cx,BEEP_DUR_OUTTER ;???
    mov al,BEEP_TONE ;???
    .lo:
    out 42h,al ;???

    push cx
    mov cx,BEEP_DUR_INNER ;???
    .li: loop .li
    pop cx
    loop .lo

    pop ax ;???
    and al,11111100b ;???
    out 61h,al ;???

    iret ;возврат изь прерывания

    int_2f_code:
    ;???
    cmp ah,0ffh
    jne .int_2f_exit
    mov al,ah
    iret
    .int_2f_exit:
    ;???
    jmp cs:old_int_2fh

    ;========================================================== =========================
    ;менюшка
    prog_data:
    ;Строки
    m_usage dB 0ah,0dh
    dB '=============Usage:=============',0ah,0dh
    dB '[alarm -c] - check current state',0ah,0dh
    dB '[alarm -HH:MM:SS] - set alarm',0ah,0dh
    dB '[alarm -x] - turn the alarm off',0ah,0dh,24h

    m_not_active dB 'Alarm is not active',0ah,0dh,24h
    m_state dB 'Alarm is set to '
    m_hhmmss dB '00:00:00',0ah,0dh,24h
    m_off dB 'Alarm has been turned off',0ah,0dh,24h
    m_off_already dB 'Alarm has already been turned off',0ah,0dh,24h
    m_set dB 'Alarm has been successfully set!',0ah,0dh,24h
    m_set_error dB 'Alarm set error!',0ah,0dh,24h



    start:

    mov si,80h ;???

    xor cx, cx ;обнуляем cx
    mov cl,[si] ;???
    add si,2 ;???

    .arg_shrch:
    jcxz .arg_out ;???
    mov al,[si] ;???
    cmp al,'-' ;???
    jz .arg_found
    inc si ;зачем?
    dec cx ;зачем?
    jmp .arg_shrch

    ;вывод
    .arg_out:
    mov ah,09h
    mov dx,offset m_usage
    int 21h

    ;Выход
    mov ax,4c01h
    int 21h


    .arg_found:

    inc si
    mov al,[si]

    ;Преобразуем в строчные буквы
    or al,20h

    ;Если с
    cmp al,'c'
    jne .chk_off


    ;==========Проверка==================
    ;Установлен ли?
    call check_install
    jc .installed
    ;Сообщение, если нет
    mov ah,09h
    mov dx,offset m_not_active
    int 21h

    ;Выход
    .exit_inst:
    mov ax,4c00h
    int 21h

    .installed:
    ;Если да

    mov ax,354ah ;???
    int 21h
    < br> mov di,bx ;???

    mov al,es:[di-3] ;???
    call make_ascii ;преобразование в АSCII

    mov word ptr m_ hhmmss,ax ;???

    mov al,es:[di-2] ;???
    call make_ascii ;преобразование в АSCII
    mov word ptr m_hhmmss+3,ax ;???

    mov al,es:[di-1] ;???
    call make_ascii ;преобразование в АSCII
    mov word ptr m_hhmmss+6,ax ;???

    ;Вывод на экран
    mov ah,09h
    mov dx,offset m_state
    int 21h

    jmp .exit_inst
    ;====================================

    .chk_off:
    ;Если -х
    cmp al,'x'
    jne .chk_set

    ;==========Выключение================
    call check_install
    jc .inst_off

    mov ah,09h
    mov dx,offset m_off_already
    int 21h

    jmp .exit_inst
    .inst_off:
    mov ah,07h ;???
    int 1ah ;???

    mov ax,354ah ;???
    int 21h
    mov di,bx ;???

    mov ah,35h ;???
    mov al,2fh ;???
    push ds
    lds dx,[di-7] ;???
    int 21h

    pop ds

    mov ah,49h ;освобождение резидента
    int 21h

    ;сообщение об успехе операции
    mov ah,09h
    mov dx,offset m_off
    int 21h

    ;====================================
    jmp .exit_inst
    .chk_set:

    call make_bcd ;???
    mov hrs,al ;???

    add si,2
    cmp byte ptr [si],':' ;???
    je .cont

    mov ah,09h
    mov dx,offset m_usage
    int 21h

    mov ax,4c01h
    int 21h
    .cont:

    inc si ;???
    call make_bcd ;???
    mov min,al ;???

    add si,2 ;???
    cmp byte ptr [si],':' ;???
    je .proceed ;???

    mov ah,09h
    mov dx,offset m_usage
    int 21h

    mov ax,4c01h
    int 21h

    .proceed:
    inc si
    call make_bcd
    mov sec,al
    ;==========Установка=================

    ;Проверка
    call check_install
    jc .no_install_on


    ;Запрет прерываний
    cli

    ;Получаем адрес 2fh(почему)
    mov ah,35h
    mov al,2fh
    int 21h

    mov word ptr old_int_2fh,bx ;???
    mov word ptr old_int_2fh+2,es ;???

    mov ah,25h ;???
    mov al,2fh ;???
    mov dx,offset int_2f_code ;???
    int 21h

    mov ah,25h ;???
    mov al,4ah ;???
    mov dx,offset int_4a_code ;???
    int 21h
    ;Разрешение прерываний
    sti


    ;???
    mov ah,06h
    mov ch,hrs
    mov cl,min
    mov dh,sec
    int 1ah

    ;Сообщение об успехе
    mov ah,09h
    mov dx,offset m_set
    int 21h

    ;???
    mov ah,31h
    mov dx,offset prog_data
    int 21h
    .no_install_on:
    ;???
    mov ah,07h
    int 1ah

    ;???
    mov ah,06h
    mov ch,hrs
    mov cl,min
    mov dh,sec

    int 1ah ;???
    jnc .install_ok ;???

    ;Вывод собщения об ошибке
    mov ah,09h
    mov dx,offset m_set_error
    int 21h

    jmp .set_exit

    .install_ok:
    ;====================================

    ;Успешная установка
    mov ah,09h
    mov dx,offset m_set
    int 21h
    .set_exit:
    mov ax,4c00h
    int 21h

    ;???
    check_install proc
    push ax
    mov ah,0ffh ;???
    xor al,al ;???
    int 2fh ;???
    add al,1 ;???
    pop ax ;???
    ;Если ah == 0ffh, CF=1
    ;CF == 0 в противном случае
    ret
    check_install endp

    ;перевод в BCD
    make_bcd proc
    mov ax,[si]
    and ax,0f0fh
    shl al,4
    or al,ah
    ret
    make_bcd endp

    ;перевод в ASCII
    make_ascii proc
    mov ah,al
    and ah,0fh
    shr al,4
    or ax,3030h
    ret
    make_ascii endp

    end begin


    Спасибо большое

    Отправлен: 21.05.2010, 16:54
    Вопрос задал: Мироненко Николай Николаевич, Практикант
    Всего ответов: 1
    Страница вопроса »


    Отвечает Зенченко Константин Николаевич, Модератор :
    Здравствуйте, Мироненко Николай Николаевич.

    Код с комментариями в приложении. Общий принцип работы. При запуске программы Вы должны использовать ключи: , и -новое время. Последний ключ ещё и запускает сам будильник.
    В программе используются прерывание , функции: 06-установить будильник и 07. При установке будильника в КМОП-микросхему записывается значение: часов:минут:секунд. На аппаратном уровне проиисходит проверка текущего времени, и если совпадает, то вызывается программное прерывание , обработчик которого есть в коде(int_4a_code:). Это простейший биппер. Включает динамик и системный таймер(бит 0 - динамик, бит 1 - таймер).
    Код:
    in     al,61h
    or al,03h
    out 61h ,al

    Аналoгичный код, но с уже сброшеными битами служит для выключения таймера и динамика.
    Команда out 42h,al - включает и выключает питание на динамик, а т.к. она расположена в цикле вместе с пустым циклом задержки .li: loop .li, то в динамике слышен звук .

    Для контроля своего присутсвия в системе используется прерывание 2F, функция 0F, именно её перехватывает обработчик int_2f_code:, и если нашего резидента нет в памяти, то функцию 0F будет обрабатывать старый обработчик, который установила система или другая программа, до этого и соответсвенно будет установлен флаг СF.
    Вроде всё. Вопросы задавайте в мини-форум.
    Удачи!

    Приложение:

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

    Ответ отправил: Зенченко Константин Николаевич, Модератор
    Ответ отправлен: 21.05.2010, 20:43
    Номер ответа: 261555
    Украина, Киев
    Тел.: +38-097-953-66-19
    Адрес: Украина, Киев

    Оценка ответа: 5
    Комментарий к оценке:
    Спасибо Вам большое!!! Пока вопросов нет :)

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

  • Вопрос № 178549:

    Уважаемые эксперты! Требуется написать программу(с комментариями) Ввести с клавиатуры две строки. Определить, равны ли они. Ввод строк с клавиатуры и команды пакетной обработки (строковые команды) в языке Assebmler. С клавиатуры вводятся только символы латинского алфавита. При выполнении каждого задания необходимо использовать команды пакетной обработки.Бонусное задание: оформить задания в виде функции, корректно передав ей параметры через стек. Буду признателен за бонус.)
    Платформа DOS, ассемблер TASM.

    Отправлен: 21.05.2010, 18:00
    Вопрос задал: Филимонов Алексей Викторович, 1-й класс
    Всего ответов: 1
    Страница вопроса »


    Отвечает Лысков Игорь Витальевич, Модератор :
    Здравствуйте, Филимонов Алексей Викторович.
    Можно сделать, например, так:
    Код:

    .model tiny, C
    .data
    ;Зададим два буфера для ввода строки по ф-и 0ah
    max1 db 129 ;максимальная длина строки1
    len1 db 0 ;реальная длина строки1
    buf1 db 129 dup (?) ;сама строка1, в конце код 0dh

    max2 db 129 ;максимальная длина строки2
    len2 db 0 ;реальная длина строки2
    buf2 db 129 dup (?) ;сама строка1, в конце код 0dh

    Prompt1 db 'Enter first string: $' ;Подсказка 1
    Prompt2 db 0dh,0ah,'Enter second string: $' ;Подсказка 2
    Msg1 db 0dh,0ah,'Strings are equals!$' ;Сообщение, что строки равны
    Msg2 db 0dh,0ah,'Strings are NOT equals!$' ;не равны
    Any db 0dh,0ah,'Press any key$' ;п онятно :)

    .code
    .startup ;точка входа
    .286
    ;Вводим первую строку
    call GetString, offset prompt1, offset max1
    ;Вводим вторую строку
    call GetString, offset prompt2, offset max2
    ;сравниваем
    call CmpStrings, offset buf1, offset buf2
    ;сообщение, что равны
    lea dx, msg1
    ;результат в ax (=0 -> равны)
    test ax, ax
    jz PrMessage
    ;сообщение, что не равны
    lea dx, msg2
    PrMessage:
    mov ah, 9
    int 21h ;выводим

    lea dx, Any
    mov ah, 9
    int 21h ;Any key

    mov ah, 0
    int 16h ;Ждем any key

    mov ax, 4c00h
    int 21h ;выходим

    ;вводим строку
    ;параметры:
    ;pPrompt - адрес строки подсказки
    ;pData - адрес буфера для ввода
    GetString proc pPrompt:word, pData:word
    mov dx, pPrompt
    mov ah, 9
    int 21h ;подсказка
    mov dx, pData
    mov ah, 0ah
    int 21h ;вводим
    ret
    GetString endp

    ;сравниваем две строки по адресам pStr1 и pStr2
    ;результат: ax=0 - р авны, ax=1 - не равны
    CmpStrings proc pStr1:word, pStr2:word
    mov ax, 1 ;считаем пока, что не равны
    mov si, pStr1 ;адрес первой строки
    mov di, pStr2 ;адрес второй строки
    CmpLoop:
    cmpsb ;сравниваем один байт [ds:si] и [es:di],si=si+1,di=di+1
    jne CmpRet ;если не равно, сразу на выход
    cmp byte ptr [si-1], 0dh ;если равно, то проверим проверенный байт,
    jne CmpLoop ; дошли ли до конца строк, признаком конца является байт 0dh
    xor ax, ax ; и если 0dh и равно, значит строки равны!
    CmpRet:
    ret
    CmpStrings endp

    end

    -----
    Удачи!

    Ответ отправил: Лысков Игорь Витальевич, Модератор
    Ответ отправлен: 22.05.2010, 17:12
    Номер ответа: 261570
    Украина, Кировоград
    Тел.: +380957525051
    ICQ # 234137952
    Mail.ru-агент: igorlyskov@mail.ru
    Абонент Skype: igorlyskov

    Оценка ответа: 5
    Комментарий к оценке:
    Спасибо вам!)

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

  • Вопрос № 178550:

    Уважаемые эксперты! Требуется написать программу(с комментариями) Вывести на экран таблицу символов ASCII, используя для вывода символов различные атрибуты цвета и фона. Вывод на экран в текстовом режиме с использованием средств DOS и BIOS.
    Бонусное задание: выполнить задание в двух вариантах, используя вывод на экран с помощью функций BIOS, и вывод напрямую в видеопамять.)
    Платформа DOS, ассемблер TASM.

    Отправлен: 21.05.2010, 18:03
    Вопрос задал: Филимонов Алексей Викторович, 1-й класс
    Всего ответов: 1
    Страница вопроса »


    Отвечает Лысков Игорь Витальевич, Модератор :
    Здравствуйте, Филимонов Алексей Викторович.
    Программа для вывода таблицы ASCII
    Сначала при помощи функции 1302h прерывания БИОС формируем аттрибуты,
    а затем в те же позиции выводим символы при помощи функции 9 прерывания ДОС
    Код:

    .model tiny
    .code
    .startup
    call PrintAttrib ;Выводим на экран аттрибуты с помощью ф-и 13h прерывания 10h
    call PrintTable ;Выводим на экран символы с помощью ф-и 9 прерывания 21h

    mov ah, 0 ;ждем нажатие на клавишу
    int 16h

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

    ;Выводим табличку ASCII кодов при помощи функции 9 прерывания 21h
    ;Выводим строками по 16 символов
    PrintTable proc
    mov dx, 0520h ;начальная позиция на экране
    mov cx, 16 ;16 строк
    mov al, 0 ;начинаем с 0
    PrintSymbolLoop: ;цикл по строкам
    push cx ;сохраним счетчик строк
    lea di, String ;сформируем в данной строке строку для вывода
    mov cx, 16 ;в строке 16 символов
    FormSymbolRowLoop: ;цикл формирования строки
    stosb ;очередной символ из al
    inc al ;инкремент кода символа
    loop FormSymbolRowLoop ;16 раз
    push dx ;сохраним позицию курсора
    push ax ;сохраним код последнего символа
    mov bh, 0 ;страница для курсора
    mov ah, 2 ;установим позицию курсора
    int 10h

    mov al,'$'
    stosb ;зароем строку для ф-и 9

    lea dx, String
    mov ah, 9
    int 21h ;выведем строку

    pop ax
    pop dx
    inc dh ;на следующую строку
    pop cx
    loop PrintSymbolLoop
    ret
    PrintTable endp

    ;Выводим табличку аттрибутов при помощи функции 1302h прерывания 10h
    ;Выводим строками по 16 символов
    PrintAttrib proc
    mov al, ' ' ;любой код
    lea di, String ;сформируем в данной строке строку д ля вывода
    lea si, Attributes ;строка аттрибутов
    mov cx, 16 ;в строке 16 символов
    FormRowLoop: ;цикл формирования строки
    stosb ;символ из al
    movsb ;очередной аттрибут
    loop FormRowLoop ;16 раз

    mov dx, 0520h ;начальная позиция на экране
    mov cx, 16 ;14 строк
    PrintLoop: ;цикл по строкам
    push cx ;сохраним счетчик строк
    push dx ;сохраним позицию курсора
    mov ax, 1302h ;функция вывода строки
    lea bp, String ;es:bp - адрес строки
    mov cx, 16 ;число символов
    mov bh, 0 ;страница видеопамяти
    int 10h ;сервис БИОС
    pop dx
    inc dh ;на следующую строку
    pop cx
    loop PrintLoop ;и так 16 раз
    ret
    PrintAttrib endp

    .data
    ;Строка с примерными аттрибутами
    Attributes db 09h,12h,20h,34h,45h,56h,67h,79h,0ah,1bh,2ch,3dh,4eh,5fh,60h,71h

    .data?
    ;строка для формирования данных для вывода
    String dw 16 dup (?)

    end

    -----
    Удачи!

    Ответ отправил: Лысков Игорь Витальевич, Модератор
    Ответ отправлен: 22.05.2010, 11:44
    Номер ответа: 261567
    Украина, Кировоград
    Тел.: +380957525051
    ICQ # 234137952
    Mail.ru-агент: igorlyskov@mail.ru
    Абонент Skype: igorlyskov

    Оценка ответа: 5
    Комментарий к оценке:
    Спасибо! благодарен.

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

  • Вопрос № 178551:

    Уважаемые эксперты! Требуется написать программу(с комментариями) Ввести с клавиатуры имя каталога и маску файлов. Перенести все соответствующие маске файлы в каталог уровнем выше указанного. Если указанный каталог остался пуст – удалить его. Работа с диском средствами DOS и BIOS. Внимание! Все работы выполняются в DOSBox (VirtualPC) с образом дискеты, иначе можно испортить данные на винчестере.(Это так маленький комментарий)) Буду очень признателен если сделаете программу.
    Платформа DOS, ассемблер TASM.

    Отправлен: 21.05.2010, 18:06
    Вопрос задал: Филимонов Алексей Викторович, 1-й класс
    Всего ответов: 1
    Страница вопроса »


    Отвечает Лысков Игорь Витальевич, Модератор :
    Здравствуйте, Филимонов Алексей Викторович.
    Программа ниже.
    При вводе ждет полный путь вместе с маской...
    Код:
    ;Ввести с клавиатуры имя каталога и маску файлов. Перенести 
    ;все соответствующие маске файлы в каталог уровнем выше указанного.
    ;Если указанный каталог остался пуст – удалить его.
    .model tiny
    .code
    .startup

    call GetMask ;вводим путь и маску, разбираем их
    jc finish ; вводить надо обязательно с '\'
    ; хотя бы? так: ".\*.*"

    call MoveFiles ;перемещаем файлы
    call DelDir ;если каталог пустой, то удаляем

    finish:
    mov ax, 4c00h
    int 21h

    GetMask proc ;вводим путь с маской
    lea dx, prompt ;подсказка
    mov ah, 9
    int 21h

    lea dx, max ;вводим путь и маску
    mov ah, 0ah
    int 21h

    xor bx, bx
    mov bl, len
    mov string[bx], 0 ;заменим 0dh на 0
    GMParseLoop: ;ищем последний '\'
    test bx, bx ;дошли до начала, '\' не нашли
    jz GMError
    cmp string[bx-1], ':' ; аналогично, только дошли до диска
    je GMError
    cmp string[bx-1], '\' ;нашли '\'
    je GMFound
    dec bx ;идем к началу
    jmp GMParseLoop
    GMFound: ;нашли последний '\'
    lea di, path ;копируем сюда, как путь директории выше
    lea si, string ;введенный путь
    mov cx, bx ;длина до '\' включительно
    rep movsb ;копируем
    mov word ptr [di], '..' ;добавим '..' для указания на путь выше
    mov word ptr [di+2], '\' ;добавим разделитель, сюда будем добавлять имя файла
    lea ax, [di+3] ;позиция имени файла
    mov pNameNew, ax ;сохраняем

    lea di, fpath ;путь до исходных файлов
    lea si, string ;введенный путь
    mov cx, b x
    rep movsb ;копируем
    mov pNameOld, di ;сохраняем позицию имени файла
    clc ;все ок
    ret
    GMError:
    lea dx, pParmError ;сообщение об ошибке
    mov ah, 9
    int 21h
    stc
    ret
    GetMask endp

    MoveFiles proc ;перемещаем файлы
    lea dx, dta
    mov ah, 1ah
    int 21h ;устанавливаем свою область DTA

    mov cx, 0 ;аттрибут - только файлы
    mov ah, 4eh ;ищем первого
    SearchLoop:
    lea dx, string ;путь с маской
    int 21h
    jc NoFiles ;не найдено - уходим

    mov di, pNameOld ;позиция в исходном пути, куда вставить имя файла
    mov bx, pNameNew ;позиция в результирующем пути, куда вставить имя файла
    lea si, dta.fname ;адрес имени файла в DTA
    formFPath:
    lodsb ;копируем имя файла
    stosb ;в оба буфера
    mov [bx], al
    inc bx
    cmp al, 0 ;вместе с последним 0
    jne formFPath

    lea dx, fpath ;ds:dx - путь с исходным именем
    lea di, path ;es:di - путь с именем, куда перенесем
    mov ah, 56 h
    int 21h ;move
    ;выведем имя файла на экран
    mov al, 0dh ;перевод строки
    int 29h
    mov al, 0ah
    int 29h
    lea si, dta.fname ;имя файла
    MFPrint:
    lodsb
    cmp al, 0
    je MFNext
    int 29h
    jmp MFPrint
    MFNext:
    mov ah, 4fh ;продолжение поиска
    jmp SearchLoop ;ищем дальше
    NoFiles:
    ret
    MoveFiles endp

    DelDir proc ;удаляем каталог
    ;проверим, совпадает ли текущий каталог с заданным
    ;для этого сначала определим диск
    lea si, string ;сюда запишем текущий путь (он будет без диска)
    lea di, fpath ;строка с путем
    mov dl, 0 ;устройство по-умолчанию, если не диск не задан
    cmp byte ptr [si+1],':' ;проверим на задание диска
    jne GetCurrentDir ;не задан - читаем текущий каталог
    mov dl, [si] ;первый символ - диск
    or dl, 20h ;делаем букву маленькой
    sub dl, 60h ;'a'-1,'b'-2,...
    lea si, [si+3] ;обойдем 'c:\'
    lea di, [di+3]
    GetCurrentDir:
    mov ah , 47h ;узнаем текущий каталог
    int 21h
    cmpPaths: ;сравним, причем без учета на большие, маленькие
    lodsb
    xor al, [di] ;для одинаковых или 0, или 20h
    jz Equal
    cmp al, 20h
    jnz notEqual ;сравниваем, пока не найдем отличие
    Equal:
    inc di
    jmp cmpPaths
    notEqual:
    cmp byte ptr [si-1], 0 ;пути отличаются
    jne ToDelete ;на удаление пути
    cmp byte ptr [di], '\' ;пути равны и в этом случае, т.к. дальше имя файла
    jne ToDelete

    lea dx, path ;равное - перейдем на уровень выше
    mov bx, pNameNew
    mov byte ptr [bx-1],0 ;закроем путь 0 в позиции '\'
    mov ah, 3bh
    int 21h ;cd ..
    ToDelete:
    lea dx, fpath ;исходный путь
    mov bx, pNameOld ;позиция пследней '\'
    mov byte ptr [bx-1],0 ;закроем путь 0 в позиции '\'
    mov ah, 3ah
    int 21h ;удаляем исходный каталог
    ret
    DelDir endp

    .data
    pParmError db 0dh,0ah,'Enter subdirectory and files mask$'
    prompt db 'Enter path and mask: $'
    max db 129 ;для ввода пути с маской
    len db 0

    .data?
    string db 129 dup ( ?) ;здесь будет введенная строка, путь с маской
    path db 129 dup (?) ;путь, куда переносим (с ..)
    fpath db 129 dup (?) ;исходный путь с именем файла
    pNameOld dw ? ;позиция в fpath, куда пишем имя файла
    pNameNew dw ? ;позиция в path, куда пишем имя файла

    DTAdata struc ;DTA для поиска
    reserve db 21 dup (?)
    attr db ?
    time dw ?
    date dw ?
    fsize dw ?, ?
    fname db 13 dup (?)
    DTAdata ends

    dta DTAdata <>

    end

    -----
    Удачи!

    Ответ отправил: Лысков Игорь Витальевич, Модератор
    Ответ отправлен: 24.05.2010, 02:28
    Номер ответа: 261604
    Украина, Кировоград
    Тел.: +380957525051
    ICQ # 234137952
    Mail.ru-агент: igorlyskov@mail.ru
    Абонент Skype: igorlyskov

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

  • Вопрос № 178552:

    Уважаемые эксперты! Требуется написать программу(с комментариями) Даны три стороны треугольника. Найти радиус описанной окружности. Операции с плавающей точкой в архитектуре x86
    Платформа DOS, ассемблер TASM.

    Отправлен: 21.05.2010, 18:10
    Вопрос задал: Филимонов Алексей Викторович, 1-й класс
    Всего ответов: 1
    Страница вопроса »


    Отвечает Лысков Игорь Витальевич, Модератор :
    Здравствуйте, Филимонов Алексей Викторович.
    Вот Вам программа, решающая задачу.
    Ввод-вывод отсутствует, т.к. это программа чисто на демонстрацию работы с сопроцессором.
    Код:

    .model tiny, C
    .data
    a dd 2.4 ;три стороны
    b dd 3.6
    c dd 4.1
    R dd 0 ;здесь будет радиус описанной окружности
    c4 dw 4 ;необходимые константы
    c2 dw 2

    .code
    .286
    .startup
    call CalcR, offset a, offset b, offset c, offset R

    mov ax, 4c00h
    int 21h

    ;вычисление радиуса описанной окружности
    ;параметры: адреса длин трех сторон и адрес радиуса
    ;все величины формата float = dword
    ;используем формулу: R=abc/4S, где S - площадь треугольника
    ;Площадь ищем по формуле S=sqrt(p(p-a)(p-b)(p-c)), где p=(a+b+c)/2
    Calc R proc pa:word, pb:word, pc:word, pr:word
    uses di, si, bx
    mov di,pa
    fld dword ptr [di] ;a
    mov si,pb
    fmul dword ptr [si] ;a*b
    mov bx,pc
    fmul dword ptr [bx] ;a*b*c

    ;ищем p
    fld dword ptr [di] ;a
    fadd dword ptr [si] ;a+b
    fadd dword ptr [bx] ;a+b+c
    fidiv c2 ;p=(a+b+c)/2

    fld st ;st=st(1)=p
    fsub dword ptr [di] ;p-a
    fld st(1) ;st=p
    fsub dword ptr [si] ;p-b
    fld st(2) ;st=p
    fsub dword ptr [bx] ;p-c
    fmulp ;(p-c)(p-b)
    fmulp ;(p-c)(p-b)(p-a)
    fmulp ;(p-c)(p-b)(p-a)p
    fsqrt ;S=sqrt((p-c)(p-b)(p-a)p)
    fimul c4 ;4S
    fdivp ;a*b*c/4S
    mov di, pr
    fstp dword ptr [di] ;сохраним результат
    ret
    CalcR endp

    end

    -----
    Удачи!

    Ответ отправил: Лысков Игорь Витальевич, Модератор
    Ответ отправлен: 22.05.2010, 10:23
    Номер ответа: 261565
    Украина, Кировоград
    Тел.: +380957525051
    ICQ # 234137952
    Mail.ru-агент: igorlyskov@mail.ru
    Абонент Skype: igorlyskov

    Оценка ответа: 4
    Комментарий к оценке:
    Спасибо) очень признателен

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

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

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

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

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

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

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

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


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

    В избранное