Консультация № 119827
23.01.2008, 12:14
50.00 руб.
0 7 1
Здравствуйте! Мне по ассемблеру задали написать программу: просмотрщик файлов в шестнадцатеричном виде. Но преподаватель её не принял, так как она не совсем корректно отображает файл (к примеру она не совсем точно показывает строчки, к примеру может перенести на новую строчку или наоборот не перенести 16-теричный вид файла). Вот это надо переделать.
Насколько я понял это происходит потому что встречается код переноса строки и программа его переносит, т.е. вроде бы надо написать проверку.
Помогите пожалуйста мне с этой проблемой, если можно то добавте в программу эту проверку или просто переделать её.

Спасибо за внимание. Надеюсь Вы мне поможите.

Приложение:
assume cs:code, ds:datadata segment pkey db "press any key...",0ah,0dh,"$" tmpfile db ‘c:\file.txt‘,0 adrfile db 64 dup(0) tmpid dw 0 id dw 0 end db 0ah,0dh,00h,00h,"$" readstr db 16 dup(0) writestr db 10 dup(0) table db "0123456789ABCDEF" number dw 0 fend db 0 divider db ‘| ‘ viewstr db 72 dup(?),"$" vflg db 0endsstack segment dw 128 dup(0)endscode segmentconvhexal proc push bx mov bx,offset table xlat pop bx retconvhexal endpformstr proc mov cx,16 mov si,offset readstrlb: mov [si],0 inc si loop lb mov ah,3fh mov bx,id mov cx,16 mov dx,offset readstr int 21h ;inc ax cmp ax,cx je l1 mov fend,1l1: mov si,offset readstr mov cx,8l2: push cx mov al,[si] shr al,4 call convhexal push si mov si,offset writestr mov [si],al pop si mov ah,40h mov bx,tmpid mov cx,1 mov dx,offset writestr int 21h mov al,[si] and al,0Fh call convhexal push si mov si,offset writestr mov [si],al pop si mov ah,40h mov bx,tmpid mov cx,2 mov dx,offset writestr int 21h inc si pop cx loop l2 mov ah,40h mov bx,tmpid mov cx,2 mov dx,offset divider int 21h mov cx,8l3: push cx mov al,[si] shr al,4 call convhexal push si mov si,offset writestr mov [si],al pop si mov ah,40h mov bx,tmpid mov cx,1 mov dx,offset writestr int 21h mov al,[si] and al,0Fh call convhexal push si mov si,offset writestr mov [si],al pop si mov ah,40h mov bx,tmpid mov cx,2 mov dx,offset writestr int 21h inc si pop cx loop l3 mov ah,40h mov bx,tmpid mov cx,2 mov dx,offset divider int 21h mov ah,40h mov bx,tmpid mov cx,16 mov dx,offset readstr int 21h mov ah,40h mov bx,tmpid mov cx,2 mov dx,offset end int 21h retformstr endpview proc mov ah,07h mov al,0 mov bh,00001111b mov ch,0 mov cl,0 mov dh,25 mov dl,79 int 10h mov ah,02h mov bh,0 mov bl,2 mov dh,0 mov dl,2 int 10h mov ah,42h mov bx,tmpid mov cx,0 mov dx,0 mov al,00h int 21h mov cx,24lbl2: push cx mov ah,3fh mov bx,tmpid mov cx,70 mov dx,offset viewstr int 21h ;inc ax cmp ax,cx je lbl1 jne extt mov vflg,1 pop cx mov cx,1 push cxlbl1: mov ah,9 lea dx,viewstr int 21h pop cx loop lbl2scroll: mov ah,00h int 16h cmp ah,01h je extt cmp ah,48h je up cmp ah,50h je dwn jmp scrollextt: jmp extup: mov ah,42h mov bx,tmpid mov cx,0 mov dx,0 mov al,01h int 21h cmp ax,1680 jbe scroll sub ax,1750 mov cx,0 mov dx,ax mov ah,42h mov bx,tmpid mov al,00h int 21h push ax mov ah,3fh mov bx,tmpid mov cx,70 mov dx,offset viewstr int 21h mov ah,07h mov al,1 mov bh,00001111b mov ch,0 mov cl,0 mov dh,25 mov dl,79 int 10h mov ah,02h mov bh,0 mov bl,2 mov dh,0 mov dl,2 int 10h mov ah,9 lea dx,viewstr int 21h pop dx add dx,1680 mov ah,42h mov bx,tmpid mov cx,0 mov al,00h int 21hscroll2: jmp scrolldwn: mov ah,42h mov bx,tmpid mov cx,0 mov dx,0 mov al,01h int 21h push ax mov ah,42h mov bx,tmpid mov cx,0 mov dx,0 mov al,02h int 21h pop bx cmp ax,bx jbe scroll2 mov dx,bx mov ah,42h mov bx,tmpid mov cx,0 mov al,00h int 21h mov ah,3fh mov bx,tmpid mov cx,70 mov dx,offset viewstr int 21h jc scroll2 mov ah,06h mov al,1 mov bh,00001111b mov ch,0 mov cl,0 mov dh,25 mov dl,79 int 10h mov ah,02h mov bh,0 mov bl,2 mov dh,23 mov dl,2 int 10h mov ah,9 lea dx,viewstr int 21h jmp scrollext: jmp eext retview endpstart: mov ax, data mov ds, ax mov es, ax mov di,offset adrfile mov [di],64 mov ah,06h mov al,0 mov bh,00001111b mov ch,0 mov cl,0 mov dh,25 mov dl,79 int 10h mov ah,02h mov bh,0 mov bl,2 mov dh,0 mov dl,0 int 10h mov ah,0ah mov dx,offset adrfile int 21h inc di xor ax,ax mov al,[di] add di,ax inc di mov [di],00h mov di,offset adrfile inc di inc di mov ah,3ch xor cx,cx mov dx,offset tmpfile int 21h mov tmpid,ax mov ah,3dh mov al,2 mov dx,offset tmpfile xor cx,cx int 21h mov ah,3dh mov al,2 mov dx,di xor cx,cx int 21h jc exit mov id,axfr: call formstr cmp fend,0 je fr mov ah,3eh mov bx,id int 21h call vieweext:exit: mov ah,3eh mov bx,tmpid int 21h mov ah,41h mov dx,offset tmpfile ;int 21hlabl: mov ah,0ch mov al,08h ;int 21h ;cmp al,27 ;jne labl mov ax, 4c00h int 21hendsend start

Обсуждение

давно
Старший Модератор
31795
6196
23.01.2008, 12:49
общий
Вам нужно информацию выводить на экран или в файл?
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
23.01.2008, 13:46
общий
Можно только на экран.
давно
Старший Модератор
31795
6196
23.01.2008, 20:08
общий
это ответ
Здравствуйте, Draconit!

В приложении программа, которая выводит в 16-ые коды и дальше в строке их символьное представление в формате(16 строк по 16 байт):
<font color=blue>68 <b>0D 0A</b> 64 77 20 6F 66 66 73 65 74 20 4E 4F 50 h<b>··</b>dw offset NOP</font>
Во время вывода 16-ых кодов производится проверка служебных кодов и их замена на символ(в примере выше, это выделенно).
Производится проверка ошибок во время выполнения:
-не удалось открыть файл;
-не удалось прочитать файл;
-не правильное имя файла;

Удачи!

Приложение:
;tasm progr;tlink progr;masm;директива компилятораequReadSize equ 16.model small.186.stack 200.datadbFileNameOpen db ‘reestra.txt‘,0dbErrorOpen db 13,10,‘Error: unable to open file$‘dbErrorRead db 13,10,‘Error: unable to read file$‘;;если эту строчку разместить после строки dbReadBuffer , то ;длину полного пути к файлу и его имени можно увеличить до 60 символовdbErrorName db 13,10,‘Error: wrong file name$‘dbStopDump db 13,10,‘End of file$‘dwHndlOpen dw ?dbCount db ?;;эта строка используется при;;- выводе сообщения для ввода имени файла;- ввода имени файла;- первые 16-байт для чтения из файла dbReadBuffer db ‘Enter file name for dump[max:35byte]$‘.code;настраиваемся на сегмент данныхstart: mov ax,@data mov ds,ax;ставим 3-ий текстовый режим и чистим экран mov ax,03 int 10h;выводим приглашение для ввода имени файла mov ah,09 mov dx,offset dbReadBuffer;запоминаем для функции 0А адрес буфера строки push dx push dx int 21h;ставим максимальное значение пути к файлу(23 байта) и имени файла(8+1+3 байт);(8-имя файла) + (1-точка) + (3-разширение) mov byte ptr[dbReadBuffer],35 mov ah,0ah pop dx int 21h;записываем маркер конца имени файла pop si xor ah,ah mov al,[si+1];проверяем длину имени файла or al,al mov dx,offset dbErrorName jz isOutMessage;вычисляем адрес маркера конца имени файла add si,ax mov [si+2],ah;открываем файл для чтения mov ax,3d20h mov dx,offset dbReadBuffer+2 int 21h;контролируем ошибку работы функции mov dx,offset dbErrorOpen jc isOutMessage mov dwHndlOpen,ax;цикл чтения файла и вывода 16 линий по 16 байтOutputPage: ;перходим в 3-ий видео режим и чистим экран mov ax,03 int 10h;будем выводить 16-ть линий mov byte ptr[dbCount],equReadSize;вывод одной линии в формате;00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................outputNext: call OutputLine;если при выходе из подпрограммы счетчик-флаг равен 0-ю, то достигли конца файла mov al,dbCount or al,al jz isEndOfFile;уменьшаем счетчик и проверяем закончился ли вывод одного кадра dec byte ptr[dbCount] jnz OutputNext;вводим символ без эхо mov ah,07 int 21h;переход на следующий кадр jmp OutputPage;закрываем открытый файлisEndOfFile: call isCloseFile;сообщение о конце файла mov dx,offset dbStopDump;вывод сообщений: достигнут конец файла и 3-и ошибки:;не удалось открыть или прочитать файл и неправильное имя файлаisOutMessage: mov ah,09 int 21h;выход из программы mov ah,4ch int 21h;закрываем открытый флагisErrorRead: call isCloseFile;корректируем стек т.к. выход по ошибке происходит из подпрограммы pop ax;для 09-ой функции будем выводить сообщение об ошибке mov dx,offset dbErrorRead jmp isOutMessage ;читаем файлOutputLine: mov ah,3fh mov bx,dwHndlOpen;из открытого файла mov cx,equReadSize;16-ть байт mov dx,offset dbReadBuffer;в буфер int 21h;проверяем ошибку работы функции jc isErrorRead push ax;запоминаем число введенных символов;устанавливаем индексный регистр на буфер прочитанных символов mov si,offset dbReadBuffer push si;запоминаем адрес буфера для 09-ой функции mov di,ax or di,di jz isStopOut;читаем очередной символisNextStep: mov al,[si];проверяем код забоя=back space cmp al,7fh jz isNoSimbol;проверяем служебные коды т.е. 31 и меньше cmp al,20h jae isSimbol;служебный код вместо него записываем точкуisNoSimbol: mov byte ptr[si],0fah;перходим к следующему символуisSimbol: inc si;запоминаем код символа push ax;сдвигаем для вывода старшего полубайта shr al,4 call OutputHex;востанавливаем код символа для вывода младшего полубайта pop ax call OutputHex;выводим пробел разделитель mov al,20h int 29h;уменьшаем счетчик dec di;проверяем окончание строки jnz isNextStep;ставим маркер конца строки вывода mov byte ptr[si],‘$‘;выводим 2-а разделительных пробела для отделения 16-ой части от символьной mov al,20h int 29h mov al,20h int 29h;из стека получаем в СХ количество прочитанных символов pop dx pop cx push cx push dx;проверяем число прочитанных символов для сдвига символьной части sub cx,equReadSize;если равно 0, то сдвигать не нужно jz isOkSize;т.к. число не прочитанных символов меньше 16-ти;переводим в отрицательное значение в абсолютное not cx inc cx;т.к. при выводе на один 16-ый код приходится 3-знакоместа;будем умножать на 3-ти mov ax,cx shl cx,1 add cx,ax;выравниваем вывод символьной частиisCorrect: mov al,20h int 29h loop isCorrect;востанавливаем начало адрес буфера вывода и выводимisOkSize: pop dx mov ah,09 int 21h;переводим строку mov al,13 int 29h mov al,10 int 29h;проверяем количество прочитанных символов;и если оно меньше 16-тиisStopOut: pop ax cmp ax,equReadSize je isNoStop;то ставим флаг конец файла xor al,al mov dbCount,al;возврат из подпрограммыisNoStop: ret;берем младший полу байтOutputHex: and al,0fh;преводим в символ or al,30h cmp al,‘9‘;контролируем 16-ые цифры jbe isNo16 add al,7;выводим в режиме телетайпаisNo16: int 29h ret;закрываем файлisCloseFile: mov ah,3eh mov bx,dwHndlOpen int 21h ret end start
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Старший Модератор
31795
6196
24.01.2008, 12:57
общий
Такой вариант подходит?
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Старший Модератор
31795
6196
24.01.2008, 13:00
общий
dbFileNameOpen db ‘reestra.txt‘,0В этой строчке у меня было имя тестового файла, ее можно удалить.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
24.01.2008, 15:42
общий
Ну, работает как надо, правда я ещё не до конца код просмотрел, чтобы если что преподавателю объяснить.А вообще, да, такой вариант подходит.Спасибо Вам большое!
давно
Старший Модератор
31795
6196
24.01.2008, 16:25
общий
Если нужно болше коментариев могу добавить или спрашивайте в мини-форуме
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Форма ответа