20:51
Обновить
Задачки на assemblere - Форум
| RSS



[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Модератор форума: aka_kludge, LeadyTOR  
Форум » ПрогрАммиРОванИе » ПроЧее » Задачки на assemblere (Задачки на assemblere)
Задачки на assemblere
aka_kludgeДата: Вторник, 15.12.2009, 17:01 | Сообщение # 1
Admin
Группа: Администраторы
Сообщений: 1058
Награды: 2
Репутация: 25
Статус: Offline
Задачи были решены мной или ещё кем нить

При копировании материала прошу указывать первоисточник

 
aka_kludgeДата: Вторник, 15.12.2009, 17:02 | Сообщение # 2
Admin
Группа: Администраторы
Сообщений: 1058
Награды: 2
Репутация: 25
Статус: Offline
Программа в приложении предлагает ввести число (длиной до 5 цифр, проверок на корректность ввода нет), затем проверяет последнюю цифру и выводит сообщение в зависимости от результата. Если есть необходимость, то можно добавить проверку на корректность введенной строки (т.е. что введено действительно число).

Code
.model tiny
data

msg    db    "Enter a number: $"
buf    db    6, 7 dup(0) ; буфер для введенной пользователем строки

msg_even    db    13,10,"The number is even",13,10,"$"
msg_odd    db    13,10,"The number is odd",13,10,"$"

code
  org    100h

start:
  mov    ah,9    ; предлагаем ввести число
  mov    dx,offset msg
  int    21h

  mov    ah,0Ah    ; буферизованный ввод
  mov    dx,offset buf
  int    21h

; Для проверки чет/нечет достаточно проверить последнюю цифру.
; Число нечетное, если младший бит установлен.
; В буфере содержатся коды символов (например, 31h (\'1\') вместо 1),
; но символ отличается от соответствующей цифры на 30h (\'0\'),  
; поэтому можно проверить код символа.

  xor    bx,bx
  mov    bl,[buf+1]    ; длина введенной строки
  test    [buf][bx+1],1    ; проверяем последнюю цифру
  mov    dx,offset msg_even    ; предполагаем четное
  jz    @@even
  mov    dx,offset msg_odd    ; нечетное
@@even:
  mov    ah,9
  int    21h

  xor    ah,ah    ; ждем нажатия любой клавиши для выхода
  int    16h

  int    20h    ; завершаем программу
end start
 
aka_kludgeДата: Среда, 16.12.2009, 14:07 | Сообщение # 3
Admin
Группа: Администраторы
Сообщений: 1058
Награды: 2
Репутация: 25
Статус: Offline
Программа запрашивает у пользователя имя файла, читает его, выводит простое меню и выполняет запрошенную операцию. Вывод файла на экран или принтер отличается только описателем (handle) устройства назначения. Печатает на принтер.

Для сборки:
tasm -l -m2 -zn 175086.asm
tlink -t 175086.obj

Code
model tiny

data

msgEnterName    db 13,10,"Input file: $"
bufFileName    db 254    ; размер буфера
lenFileName    db 0    ; длина введенной строки
szFileName    db 254 dup(0)    ; сюда будет помещено имя файла при вводе
msgOpenError    db 13,10, "Cannot open file.",13,10,"$"
msgLSeekError    db 13,10, "lseek error",13,10,"$"
msgReadError    db 13,10, "read error",13,10,"$"
msgWriteError    db 13,10, "write error",13,10,"$"
msgOutOk    db 13,10,10
   db "-----------------------------<WBR>----",13,10
   db "Operation completed successfully.",13,10,"$"

menu    db    13,10, "What is your choice?",13,10
  db    "1   - Show file on screen",13,10
  db    "2   - Print file",13,10
  db    "Esc - exit",13,10,"$"

hFileIn  dw    0
hFileOut    dw    0
nFileSize    dd    0

; сегмент данных будет помещен после сегмента кода, так что эта метка
; будет указывать на первый свободный байт. В нашем распоряжении для данных
; находится почти целый сегмент (за вычетом PSP, кода нашей программы и стека,
; который находится в самом конце сегмента). Мы будем использовать только 16k
; (BLOCK_SIZE), что в разы меньше свободной части сегмента.

file_buf    label byte

BLOCK_SIZE    EQU    16*1024    ; размер блока для чтения/записи файла

code
  org    100h
start:
  mov    ah,9    ; выводим приглашение ввести имя файла
  mov    dx,offset msgEnterName
  int    21h

  mov    ah,0Ah    ; ввод имени файла
  mov    dx,offset bufFileName
  int    21h

  ; преобразуем имя файла в ASCIIZ строку (с конечным нулем)
  xor    bh,bh
  mov    bl,[lenFileName]
  mov    [szFileName][bx],0

  mov    ax,3D00h  ; открываем файл с доступом по чтению
  mov    dx,offset szFileName    ; смещение имени файла
  int    21h
  jnc    _open_ok

  ; AX содержит код ошибки, для простоты его игнорируем
  ; В серьезной программе надо выводить осмысленное сообщение
  ; в соответствии с кодом.

  mov    dx,offset msgOpenError    ; сообщение об ошибке открытия

_error_exit:
  mov    ah,9
  int    21h

  mov    ax,4C01h    ; завершаем программу с кодом 1
  int    21h

_open_ok:
  mov    [hFileIn],ax    ; сохраняем описатель (handle) файла

_show_menu:
  mov    ah,9  ; показываем меню
  mov    dx,offset menu
  int    21h

  ; ждем выбора пользователя
_wait:
  xor    ax,ax
  int    16h
  cmp    al,\'1\'
  je    _type
  cmp    al,\'2\'
  je    _print
  cmp    al,27    ; ESC
  jne    _wait

  mov    ax,4C00h    ; завершаем программу с кодом 0
  int    21h

_type:
  mov    [hFileOut],1  ; стандартное устройство вывода (обычно - экран)
  jmp    short _common_out

_print:
  mov    [hFileOut],4  ; стандартный принтер
_common_out:
  ; определяем длину файла
  mov    ax,4202h    ; перемещаем указатель в конец
  mov    bx,[hFileIn]
  xor    cx,cx
  xor    dx,dx
  int    21h
  jnc    _size_ok
_lseek_error:
  mov    dx,offset msgLSeekError
  jmp    _error_exit

_size_ok:
  mov    word ptr [nFileSize],ax
  mov    word ptr [nFileSize+2],dx

  ; возвращаем указатель в начало файла, BX уже содержит нужное значение
  mov    ax,4200h
  xor    cx,cx
  xor    dx,dx
  int    21h
  jc    _lseek_error

; в цикле читаем и записываем файл на устройство вывода
; буфер - в конце программы (см. комментарий к file_buf)

386
; поскольку процессор не указан, упрощаем себе работу с длинными целыми
  mov    eax,[nFileSize]
_next_block:
  mov    ecx,BLOCK_SIZE
  sub    eax,ecx
  jae    _save_new_size    ; беззнаковое вычитание
  xor    eax,eax
  mov    ecx,[nFileSize]
_save_new_size:
  mov    [nFileSize],eax
  ; ECX содержит размер очередного блока (<=BLOCK_SIZE)
8086
  mov    dx,offset file_buf
  mov    bx,[hFileIn]

  mov    ah,3Fh    ; читаем кусок из файла
  int    21h
  jnc    _read_ok
  mov    dx,offset msgReadError
  jmp    _error_exit

_read_ok:
  mov    cx,ax    ; размер прочитанного блока может быть меньше запрошенного

  mov    bx,[hFileOut]
  mov    ah,40h    ; записываем кусок на выбранное пользователем устройство
  int    21h
  jnc    _write_ok
  mov    dx,offset msgWriteError
  jmp    _error_exit
_write_ok:
386
  mov    eax,[nFileSize]
  test    eax,eax
8086
  jnz    _next_block

  mov    ah,9
  mov    dx,offset msgOutOk
  int    21h
  jmp    _show_menu

end    start
 
aka_kludgeДата: Пятница, 18.12.2009, 08:41 | Сообщение # 4
Admin
Группа: Администраторы
Сообщений: 1058
Награды: 2
Репутация: 25
Статус: Offline
при нажатии клавиши F или ALT+F осуществить поиск меток тома на всех логических дисках и вывести их в текстовый файл, который будет назван по текущему системному времени

Code
assume    cs:CSEG,ds:CSEG,es:CSEG,ss:<WBR>CSEG
CSEG    segment
  org    100h
Start:
  mov    ah,9
  mov    dx,offset String
  int    21h
Next_key:
  mov    ah,8    ;ждем клавишу (лучше использовать ДОС-овскую функцию,
  int    21h    ; т.к. она дает расширенные коды)
  cmp    al,\'f\'    ;f
  jz    F_pressed
  cmp    al,21h    ;alt-f
  jne    Next_key

F_pressed:  ;поехали <img src="http://s11.ucoz.net/sm/23/smile.gif" border="0" align="absmiddle" alt="smile">
  lea    dx,DTA
  mov    ah,1ah
  int    21h    ;сначала поменяем DTA, необходимую для поиска

  call    open_file    ;создадим и откроем файл с именем текущей даты
  mov    di,ax    ;сохраним handle файла

  mov    si,1    ;начинаем обход всех дисков с A:
MLoop:
  mov    bx,si    ;Флоппи и флеш-диски и другие removable не рассматриваем
  mov    ax,4408h
  int    21h
  jc    MNext    ;если ошибка (например, устройства нет вообще)
  test    ax,ax
  jz    MNext    ;0-removable

  mov    ax,4409h;также обойдем CD, DVD, SUBST и сетевые диски
  int    21h
  jc    MNext
  test    dh,10010000b    ;бит 15 - subst-drive, бит 12 - remote-drive
  jnz    MNext
    ;Ура! Hard-drive: узнаем имя тома и выведем в файл
  lea    bx,buffer    ;буфер для строки
  xchg    bx,di  ;bx = handle файла, di = адрес буфера
  mov    ax,\':@\'  ;заготовка для \'A:\' для буковки диска
  add    ax,si  ;1 - \'A\',...
  stosw   ;в буфер
  mov    word ptr path,ax;одновременно формируем строку для поиска имени тома
  mov    al,\' \'  ;отделим пробелом
  stosb

  lea    dx,path  ;ищем
  mov    ah,4eh
  mov    cx,8  ;volume label !
  int    21h
  jc    MNext  ;ошибка...
  push    si  ;в si у нас номер устройства, сохраним в стеке
  lea    si,DTA+1eh    ;адрес имени тома в DTA (заканчивается 0)
CopyLoop:
  lodsb   ;скопируем в буфер
  test    al,al
  jz    endl
  stosb
  jmp    CopyLoop
endl:
  pop    si
  mov    ax,0a0dh    ;конец строки
  stosw
  lea    dx,buffer    ;адрес буфера
  mov    cx,di
  sub    cx,dx  ;длина строки
  mov    ah,40h
  int    21h  ;пишем в файл
  mov    di,bx  ;сохраним handle файла
MNext:
  inc    si  ;на следующее устройство
  cmp    si,\'Z\'-\'A\'+1    ;до \'Z\'
  jbe    MLoop
   
  mov    ah,3eh  ;закроем файл
  int    21h

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

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

open_file    proc  ;формируем имя файла из текущего времени
  mov    ah,2ch  ;запрос времени
  int    21h
  mov    al,ch  ;часы
  aam   ;хитрая команда <img src="http://s11.ucoz.net/sm/23/smile.gif" border="0" align="absmiddle" alt="smile"> превращает число из al в неупакованный BCD
  xchg    al,ah  ; надо поменять местами (пусть в al будет старшая цифра)
  or    ax,\'00\'  ;превратим числа в символы
  mov    hours,ax    ;сохраним

  mov    al,cl  ;аналогично с минутами
  aam
  xchg    al,ah
  or    ax,\'00\'
  mov    minutes,ax

  lea    dx,FName    ;имя файла
  mov    cx,0  ;без атрибутов
  mov    ah,3ch  ;создаем и открываем одновременно
  int    21h
  ret   ;вернем в ax handle файла
open_file    endp

String    db    \'Press f or alt+f:$\'
Finish    db    0dh,0ah,\'MISSION COMPLETE. press any key$\'

FName    label    byte
hours    dw    0
  db    \'_\'
minutes    dw    0
  db    \'.txt\',0

path    db    \'a:\*.*\',0
DTA    db    43 dup (0)
buffer    db    17 dup (0)

CSEG    ends
  end    Start
 
aka_kludgeДата: Пятница, 18.12.2009, 08:41 | Сообщение # 5
Admin
Группа: Администраторы
Сообщений: 1058
Награды: 2
Репутация: 25
Статус: Offline
1 Ввод пятиразрядных чисел в ячейки ОЗУ. Программа должна обеспечить ввод последовательности ASCII-кодов десятичных цифр (не длиннее пяти), перекодировку в "8421", упаковку в десятичное число (первый введенный символ - старшая цифра) и размещение в ячейке ОЗУ. ASCII-коды не-цифр игнорировать

Code
RD #0 ;сначала будет 0
wr R1 ;здесь будем накапливать наше число
RD #5 ;максимум 5 цифр
wr R5 ;сохраним
RDI #101 ;команда очистки буфера
out 1 ; для клавиатуры
RDI #102 ; команда сброса ошибки
out 1 ; для клавиатуры
RDI #10 ; команда разрешения МВУ
OUT 1 ; для клавиатуры без прерываний (по опросу)
RDI #103 ; команда установки посимвольного ввода
out 1 ; для клавиатуры
LOOP:IN 2 ; читаем регистр состояния клавиатуры
DIV #10 ; делим на 10, чтобы второй разряд готовности стал в первом разряде
WR R3 ; сохраним
DIV #2 ; разделим на 2
MUL #2 ; умножим на 2
SUB R3 ; отнимем сохранное
JZ LOOP ; если четное, то нет кода в буфере, идем на цикл
IN 0 ; считываем код с клавиатуры
wr R2 ; сохраним
jz SAVE ; было просто нажатие на "Завершить ввод"
sbi #48 ; <\'0\' ;проверим на цифру
js RESET ; игнорируем, на сброс клавиатуры
sbi #10 ; >\'9\'
jns RESET ; игнорируем, на сброс клавиатуры
adi #10 ;восстановим число 0-9
wr r2 ; сохраним
rd r1 ; наше число
mul #10 ; умножаем на 10
add r2 ; добавляем введенный символ
wr r1 ; и на сохранение
jrnz r5,RESET ; ждем максимум 5 цифр
SAVE:rd #100 ;адрес ячейки, куда запишем результат
wr r0 ; будем адресовать через R0
rd r1 ; введенное число
wr @r0 ; сохраняем в памяти
hlt ; останов
RESET:RDI #101 ; команда сброса
out 1 ; в клавиатуру
RDI #103 ; команда установки посимвольного ввода (сбрасывается при сбросе)
out 1 ; в клавиатуру
jmp LOOP ; на чтение состояния клавиатуры
 
aka_kludgeДата: Понедельник, 28.12.2009, 09:17 | Сообщение # 6
Admin
Группа: Администраторы
Сообщений: 1058
Награды: 2
Репутация: 25
Статус: Offline
чтения отдельного бита регистра
запись отдельного бита регистра
вводить с клавиатуры значение в переменную и также как выводить значение переменной, например целочисленное на экран

Code
    .model    tiny
  .data
mess_1    db    \'Enter number (0-65535): $\'
mess_2    db    0dh,0ah,\'Hex: $\'
mess_3    db    0dh,0ah,\'Enter reading bit number (0-15): $\'
mess_4    db    0dh,0ah,\'Enter setting bit number (0-15): $\'
mess_5    db    0dh,0ah,\'Result : $\'
mess_6    db    0dh,0ah,\'Overflow. Repeat\',0dh,0ah,\'$\'
mess_7    db    0dh,0ah,\'Enter bit (0-1): $\'
mess_8    db    0dh,0ah,\'Press any key for exit$\'
input    label    byte  ;буфер для ввода числа
max    db    6  ;максимальный размер буфера (+1 позицию для кода 0dh)
len    db    0  ;реальная длина строки
buffer    db    6 dup (0)    ;сама строка
number    dw    0  ;наше число

  .code
  .startup
;Введем число
  lea    di, mess_1    ;адрес сообщения
  call    GetNumber    ;ввод числа с проверкой на переполнение слова
  mov    number, ax    ;сохраним

;Вывод в виде hex (чтобы легче было смотреть биты)
  lea    dx, mess_2    ;сообщение
  mov    ah, 9
  int    21h
  mov    ax, number    ;введенное число
  call    PrWHex  ;вывод строки Hex

;Узнаем бит в какой-либо позиции
;Введем номер бита (0-15)
  mov    max,3  ;ждем макс 2 символа
  lea    di, mess_3    ;сообщение
GetBit1:
  call    GetNumber    ;Вводим число
  cmp    ax, 16  ;должно быть < 16
  jb    bit1_ok
  lea    dx, mess_6    ;сообщение о переполнении
  mov    ah, 9
  int    21h
  jmp    GetBit1  ;на повтор ввода
bit1_ok:
  mov    cx, ax  ;номер бита
  lea    dx, mess_5    ;выведем строку  
  mov    ah, 9
  int    21h
;сформируем маску бита
  mov    ax, 1  ;один бит в 0 позиции
  shl    ax, cl  ;сдвинем на номер бита
  and    ax, number    ;выделим только один бит из number
  mov    dl, \'0\'  ;пусть пока будет 0
  jz    bit1_pr  ;если бит = 0, то на вывод
  inc    dl  ;если 1, то и выведем символ \'1\'
bit1_pr:
  mov    ah, 2  ;0-1 на экран
  int    21h

;Установим бит
  lea    di, mess_4    ;сообщение
GetBit2:
  call    GetNumber    ;введем номер бита
  cmp    ax, 16  ;проверим 0-15
  jb    bit2_ok
  lea    dx, mess_6
  mov    ah, 9
  int    21h
  jmp    GetBit2
bit2_ok:
  mov    cx, ax  ;номер бита
  mov    ax, 1  ;формируем маску бита
  shl    ax, cl
  not    ax  ;инверсия, чтобы нужный бит стал 0, остальные - 1
  and    number,ax    ;сбрасываем указанный бит
;Введем новое значение бита 0-1
  mov    max, 2  ;максимум 1 символ
  lea    di, mess_7    ;сообщение
GetBit3:
  call    GetNumber    ;вводим
  cmp    ax, 2  ;проверим 0-1
  jb    bit3_ok
  lea    dx, mess_6
  mov    ah, 9
  int    21h
  jmp    GetBit3
bit3_ok:
  shl    ax, cl  ;бит 0-1 сдвигаем до нужной позиции
  or    number, ax    ;и вставляем в наше число

;Выводим результат
  lea    dx, mess_5    ;Сообщение
  mov    ah, 9
  int    21h

;Выводим как десятичное число
  mov    ax, number
  call    PrintNumber

;Выводим как hex
  lea    dx, mess_2
  mov    ah, 9
  int    21h
  mov    ax, number
  call    PrWHex  ; Hex string

;Приглашение нажать на любую клавишу
  lea    dx, mess_8
  mov    ah, 9
  int    21h

  mov    ah,0
  int    16h
  .exit    0

GetNumber    proc  ;ввод числовой строки в буфер и преобразование строки в число
  push    cx
GetNumberStart:
  mov    dx, di  ;адрес сообщения  
  mov    ah, 9  ;(сначала в di, чтобы иметь адрес для повтора
  int    21h  ; в случае переполнения)

  lea    dx, input    ;ждем строку
  mov    ah, 0ah
  int    21h  ;в буфере строка

  xor    bx, bx  ;здесь будет наше число
  xor    cx, cx
  mov    cl, len  ;длина строки
  jcxz    GetNumber_ret    ;ничего не введено
  lea    si, buffer    ;адрес строки
GetNumber_loop:
  cmp    byte ptr [si],\'0\';проверим на код \'0\'-\'9\'
  jb    GetNumber_ret  ;иначе заканчиваем ввод
  cmp    byte ptr [si],\'9\'
  ja    GetNumber_ret
  mov    ax, 10  ;будем умножать на 10 (число десятичное)
  mul    bx  ;ранее обработанные разряды умножаем на 10
  jc    overflow    ;Переполнение!!!
  mov    bx, ax
  lodsb
  and    ax, 0fh  ;символ \'0\'-\'9\' -> число 0-9
  add    bx, ax  ;и прибавим очередной разряд
  jnc    GetNumberNext    ;на анализ следующего разряда
overflow:
  lea    dx, mess_6    ;Переполнение!!!
  mov    ah, 9
  int    21h
  jmp    GetNumberStart    ;вводим заново
GetNumberNext:
  loop    GetNumber_loop    ;по всем цифрам
GetNumber_ret:
  mov    ax, bx  ;в ax принятое число
GetNumberRet:
  pop    cx
  ret
GetNumber    endp

PrintNumber    proc  ;преобразование числа в строку и вывод на экран
  mov    bx, 10  ;будем делить на 10
  xor    cx, cx  ;счетчик разрядов
div_loop:
  xor    dx, dx  ;будем делить dx:ax/bx
  div    bx
  push    dx  ;сохраним остаток (очередной разряд)
  inc    cx  ;считаем разряды
  test    ax, ax  ;пока есть что, повторяем
  jnz    div_loop
pr_loop:   ;выводим в обратном порядке!
  pop    dx  ;извлекаем очередную цифру из стека
  or    dl, \'0\'  ;преобразуем число в символ!
  mov    ah, 2  ; и выведем
  int    21h
  loop    pr_loop
  ret
PrintNumber    endp

PrWHex    proc   ;преобразование числа и вывод, как hex-строки
  push    ax
  mov    al, ah  ;старший байт
  call    PrBHex
  pop    ax  ;младший байт
PrBHex: push    ax
  shr    al, 4  ;старший полубайт
  call    PrHDig
  pop    ax
  and    al,0fh  ;младший полубайт
PrHDig: add    al, 90h  ;0-f -> \'0\'-\'f\'
  daa
  adc    al, 040h
  daa
  mov    ah,29h  ;выведем
  int    29h
  ret
PrWHex    endp

  end
 
aka_kludgeДата: Понедельник, 28.12.2009, 09:19 | Сообщение # 7
Admin
Группа: Администраторы
Сообщений: 1058
Награды: 2
Репутация: 25
Статус: Offline
пример программы с использованием DOS функции 4Dh (получение кода возврата подпроцесса). Хитрость в том, что прежде, чем получить код возврата, надо запустить какую-то программу. Поэтому, фактически, это задача на использование ф-и 4Bh — Exec. Соответственно, бОльшая часть кода — это подготовка к вызову Exec. Исполняемый модуль задается в строке szProgName. Для примера запускается TASM.

Code
locals @@
model tiny

STACK_SIZE EQU    4096    ; резервируемый стек для нашей программы

; структура для ф-и 4Bh Exec
t_exec_param struc
  wEnvSeg  dw    ?
  pCmdLineOffs    dw    ?
  pCmdLineSeg    dw    ?
  lpFCB1Offs    dw    ?
  lpFCB1Seg    dw    ?
  lpFCB2Offs    dw    ?
  lpFCB2Seg    dw    ?
t_exec_p aram ends

; неоткрытый FCB (для первого и второго параметров командной строки)
t_FCB    struc
  bDrvID  db    0    ; drive ID
  abName       db    \'        \'
  abExt      db    \'   \'
  wCurBlock    dw    0    ; current block number
  wRecSize    dw    80h    ; logical record size
  lFileSize    dd    ?    ; length of file
  rDate  dw    ?    ; Date created/last modified in FileTimeRec format
  rTime  dw    ?    ; Time created/last modified in FileDateRec format
  res  db 8 dup(?)    ; (reserved, undocumented)
  wCurRecNo    dw    0    ; current position in current block (0-7fH)
  lRndmRecNo    dd    0    ; current record number in entire file
t_FCB    ends

data

msgExecError    db \'Cannot execute: \'
; здесь используется маленький трюк: при выводе сообщения об ошибке будет
; напечатано также имя запускаемой программы, поэтому порядок
; msgExecError и szProgName в данном примере важен, также как и 13, 10, \'$\'
; после имени программы

; для примера запускаем эту программу
szProgName    db \'c:\bc\bin\tasm.exe\', 0, 13, 10, \'$\'
szCmdLine    db 0, 13    ; командная строка - пустая

FCB1    t_FCB <>    ; первый неоткрытый FCB
FCB2    t_FCB <>    ; второй неоткрытый FCB

; параметры для ф-и 4Bh Exec
exec_param    t_exec_param <0,szCmdLine,0,FCB1,0,FCB2,0>

msgExit    db 13,10,10,\'Exit method: $\'
ex0    db \'normal termination$\'
ex1    db \'Ctrl-Break termination$\'
ex2    db \'termination via critical error$\'
ex3    db \'termination via Fn 31H KEEP$\'
ex_meth    dw ex0, ex1, ex2, ex3

msgCode    db 13,10,\'Exit code = \'
strCode    db \'...\',13,10,10
  db \'Press any key to exit...$\'

end_of_program    label    byte

code
startup
286

; Перед запуском дочернего процесса надо освободить для него память,
; поскольку наша программа получила всю имеющуюся в наличии.
; Наша программа в формате COM, поэтому, прежде всего, перемещаем стек.

; вычисляем новое положение стека, для него резервируем STACK_SIZE байт
; после конца программы
  mov    ax,offset end_of_program+STACK_SIZE+15
  and    ax,0FFF0h    ; округление до параграфа
  mov    di,ax
  mov    bx,di
  dec    di
  dec    di
  mov    si,0FFFEh    ; адрес самого "глубокого" слова в стеке
  xor    cx,cx
  sub    cx,sp  ; CS = кол-во байт в стеке (в данном случае - одно слово)
  sub    ax,cx  ; новое смещение вершины стека
  shr    cx,1  ; кол-во слов в стеке
  std
  rep movsw  ; перемещаем содержимое
  ; до этого момента прерывания (если были) использовали "старый" стек
  mov    sp,ax
  ; а теперь будет использоваться "новый" стек

  shr    bx,4  ; желаемый размер блока в параграфах
  mov    ah,4Ah  ; изменение размера блока, ES = сегмент блока
  int    21h  ; блок уменьшался, ошибки быть не должно

  mov    ax,DS  ; заполняем поля сегмента в дальних указателях
  mov    [exec_param.pCmdLineSeg],ax
  mov    [exec_param.lpFCB1Seg],ax
  mov    [exec_param.lpFCB2Seg],ax

  mov    ax,4b00h    ; загрузить и выполнить программу
  mov    dx,offset szProgName    ; DS:DX - адрес пути исполняемой программы
  mov    bx,offset exec_param    ; EX:BX - адрес блока параметров
  int    21h
  jnc    @@exec_ok
  mov    dx,offset msgExecError    ; сообщение об ошибке и выход
  jmp    short @@last_msg
@@exec_ok:
  mov    ah,4Dh  ; получить код завершения
  int    21h  ; на выходе: AH - метод завершения, AL - код ошибки
  cmp    ah,3
  ja    @@type_code

  push    ax  ; сохраняем код ошибки
; для методов завершения у нас сформирован массив указателей на строки
; вычисляем адрес нужной строки и загружаем его в DX
  mov    bl,ah
  xor    bh,bh
  shl    bx,1  ; адрес - 2 байта
  mov    ah,9  ; вывод сообщения на стандартное устройство вывода (экран)
  mov    dx,offset msgExit    ; DS:DX - адрес сообщения, заканчивающегося \'$\'
  int    21h
  mov    dx,[ex_meth][bx]
  int    21h
  pop    ax  ; восстанавливаем код ошибки

@@type_code:
; Преобразуем код ошибки в строку.
; Код - 1 байт, поэтому делаем по-простому, преобразуем байт в 3 цифры
  cld
  mov    di,offset strCode
  xor    ah,ah
  mov    bl,100
  div    bl
  add    al,\'0\'    ; число - в символ
  stosb
  mov    al,ah
  xor    ah,ah
  mov    bl,10
  div    bl
  add    al,\'0\'
  stosb
  add    ah,\'0\'
  mov    [di],ah

  ; печатаем код ошибки (код завершения) и предложение нажать клавишу для выхода
  mov    dx,offset msgCode
@@last_msg:
  mov    ah,9
  int    21h

  xor    ah,ah    ; ждем нажатия любой клавиши (чтобы увидеть результат,
  int    16h    ;    прежде чем консоль в Windows закроется)
@@exit:
  mov    ax,4C00h    ; завершаем программу с нулевым кодом
  int    21h
end
 
aka_kludgeДата: Четверг, 01.04.2010, 16:51 | Сообщение # 8
Admin
Группа: Администраторы
Сообщений: 1058
Награды: 2
Репутация: 25
Статус: Offline
надо переименовать файл

Code
Есть такая замечательная функция MoveFile из kernel32.dll   
© Цитата: MSDN
The MoveFile function renames an existing file or a directory (including all its children).  
BOOL MoveFile(
LPCTSTR lpExistingFileName, // pointer to the name of the existing file
LPCTSTR lpNewFileName // pointer to the new name for the file
);

Parameters  

lpExistingFileName
Pointer to a null-terminated string that names an existing file or directory.

lpNewFileName
Pointer to a null-terminated string that specifies the new name of a file or directory. The new name must not already exist. A new file may be on a different file system or drive. A new directory must be on the same drive.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The MoveFile function will move (rename) either a file or a directory (including all its children) either in the same directory or across directories. The one caveat is that the MoveFile function will fail on directory moves when the destination is on a different volume.
 
Форум » ПрогрАммиРОванИе » ПроЧее » Задачки на assemblere (Задачки на assemblere)
  • Страница 1 из 1
  • 1
Поиск:

Профиль
ИнформацияУправление
Сегодня: 25, 25.04.2024, 20:51
Вы используете: " v "
ВаШ внешний IP: "3.17.162.247"
У вас новых личных сообщений · Мой профиль | Выход




    Главная      
...
На службе : дней

20:51
Обновить


Пользователи
aka_kludge
qwerty
LeadyTOR
aka_Atlantis
AdHErENt
mAss
Sissutr
hiss
DrBio
tHick

Поиск


Copyright tHR - TeAM 2024 г. admin: aka_kludge (ICQ:334449009) Moderator's: LeadyTOR, ... Яндекс.Метрика