Всем здравствуйте. К сожалению, пока я здесь новичок, поэтому, возможно, написал сообщение не в соответствующий раздел (но этот показался мне самым подходящим). Перво-наперво, конечно, хотелось познакомиться с людьми, изучающими asm, не только с "бывалыми", но и новичками. Хотелось бы не только просить, но и в чём-то помогать, правда, пока я мало на что сгожусь. Это было предисловие, а вот собственно вопрос. Начал изучать ассемблер по книге Калашникова, но это мне показалось недостаточным. К концу темп в его рассылке серьёзно ускоряется, поэтому я сам себе задаю усложнённые промежуточные примеры. В одном из них - в отладчике программа работает прекрасно, но в деле никак. Вот задача. а). Программа hello.com выводит строку "Hello, world!". Я хочу создать другую программу-патч, которая исправила бы com-файл, а точнее строчку "Hello, world!" на "Goodbye, world". Вот текст первой программы, помещаемой в каталог с нашей под именем hello.com (её объяснять не надо): Код (Text): CSEG segment assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG org 100h Begin: mov ah,9 mov dx,offset Message int 21h int 20h Message db 'Hello, world!$' CSEG ends end Begin Моя логика была следующая. Строка "Hello, world!" в com-файле находится по адресу, на 9h больше, чем начало (100h). Я "закину" программу в конец своей, исправлю там строчку, и снова запишу (с использованием rep movb). Вот её код. Код (Text): .286 CSEG segment assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG org 100h begin: ;Данная программа будет обновлять файл ;hello.com ;Первоначально откроем файл RW mov ax,3D02h mov dx,offset File_name int 21h jc Message_bad ;Если файл существует, сохраняем номер файла mov Handle,ax mov bx,ax ;Чтение в память mov ah,3Fh ;Определяем количество читаемых байт (напр. 65000) mov cx,0FDE8h ;По адресу памяти за нашей программой mov dx,offset Finish int 21h ;Файл в нашей памяти. Строка Hello, world находится в db ;в смещении 109h от начала программы hello, т.е. через 9 байт ;У нас она располагается тоже через 9 байт, но после конца (Finish equ $) ;Определим её настоящий адрес add dx,9h ;Переносим 15 букв c адреса смещения переменной New_phrase ;на новый адрес dx (конец нашей програмы + 9 байт) mov si,offset New_phrase mov di,dx mov cx,15 rep movsb ;Смотрим отладчик - файл прочтён и строка в памяти заменилась! ;Подпрограмма успешного вывода строки и выхода Message_ok: ;Сначала сохраним файл, восстановив bx mov bx,Handle mov ah,3Eh int 21h ;Выводим строку mov ah,9 mov dx,offset Mess_ok int 21h int 20h ;Подпрограмма безуспешного вывода строки и выхода Message_bad: mov ah,9 mov dx,offset Mess_bad int 21h int 20h ;Имя файла File_name db 'hello.com',0,'!$' ;Успешное сообщение Mess_ok db 'Файл обновлён. Всем спасибо.$' ;Плохое сообщение Mess_bad db 'Файл не найден. Поместите hello.com в каталог с программой.$' ;Определяем переменную Handle dw 0FFFFh ;Новая фраза, которая заменяет Hello, world New_phrase db 'Goodbye, world!$' ;Переменная для вычисления длины файла Finish equ $ CSEG ends end begin Всё бы ничего, но программа ничего не меняет, в отладчике меняется прекрасно, ошибок записи в ax не выводит. Да и это легко проверить, например, заменю код Код (Text): mov si,offset New_phrase mov di,dx mov cx,15 rep movsb на другой, который добавляет в самый конец цифру "1" к файлу hello.com: Код (Text): mov ah,40h mov dx,offset addFile1 mov cx,1 int 21h Разумеется, в конец нашего файла также кидаем Код (Text): addFile1 db '1' К файлу hello.com добавляется в конец цифра 1 - то есть с остальной частью всё в порядке? Почему же в памяти программа меняет текст, а в файл не записывает, хотя сохранение hello.com отрабатывает без ошибок? Спрашивал всех знакомых программистов, никто не может подсказать. В поиске ответа не нашёл. Также, этот вопрос, как я понимаю, не подпадает под тему "Лабораторная работа". Ещё раз извиняюсь, если не туда отписался (просто удалите сообщение, если что не так).
Ты изменений то в файле своем hello.com не делаешь никаких. Ты всего-лишь изменяешь строку в копии этого файла в памяти запущенной программы, и всё это бесследно исчезает после завершения проги.
Я в вашей второй программе не вижу настройку сегментных регистров, может в этом проблемма? assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG
bendme Спасибо огромное! А как же функция 3Eh, сохраняющая его? Ведь функция с добавлением в конец файла (40h) в этом случае работает? И что надо тогда сделать, чтобы изменения-таки внести? pashe4ka13 в самом верху она.
Функция 3Еh только закрывает файл http://www.codenet.ru/progr/dos/int_0026.php А запись в файл идет через функцию 40h. Еще понадобится 42-ая функция для установки места, в которое будет записываться инфа в открытый файл. А читать файл вабще не требуется в этой задаче.
bendme, огромное спасибо! По Вашим словам, будет работать примерно так (и работает): Код (Text): .286 CSEG segment assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG org 100h begin: ;Данная программа будет обновлять файл ;hello.com ;Первоначально откроем файл RW mov ax,3D02h mov dx,offset File_name int 21h jc Message_bad ;Если файл существует, сохраняем номер файла mov Handle,ax mov bx,ax ;Устанавливаем указатель с начала файла +9h mov dx,9h mov cx,0h mov ax,4200h int 21h ;Записываем 16 символов (в т.ч.$) из смещения New_phrase по адресу, ;указанному выше mov ah,40h mov dx,offset New_phrase mov cx,16 int 21h ;Подпрограмма успешного вывода строки и выхода Message_ok: ;Сначала сохраним файл, восстановив bx mov bx,Handle mov ah,3Eh int 21h ;Выводим строку mov ah,9 mov dx,offset Mess_ok int 21h int 20h ;Подпрограмма безуспешного вывода строки и выхода Message_bad: mov ah,9 mov dx,offset Mess_bad int 21h int 20h ;Имя файла File_name db 'hello.com',0,'!$' ;Успешное сообщение Mess_ok db 'Файл обновлён. Всем спасибо.$' ;Плохое сообщение Mess_bad db 'Файл не найден. Поместите hello.com в каталог с программой.$' ;Определяем переменную Handle dw 0FFFFh ;Новая фраза, которая заменяет Hello, world New_phrase db 'Goodbye, world!$' ;Переменная для вычисления длины файла Finish equ $ CSEG ends end begin У меня же интерес именно в применении rep movsb. Но правильно я понимаю, если всё же его применять, моя программа станет выглядеть следующим образом (используется и 40h, и 42h): Код (Text): .286 CSEG segment assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG org 100h begin: ;Данная программа будет обновлять файл ;hello.com ;Первоначально откроем файл RW mov ax,3D02h mov dx,offset File_name int 21h jc Message_bad ;Если файл существует, сохраняем номер файла mov Handle,ax mov bx,ax ;Чтение в память mov ah,3Fh ;Определяем количество читаемых байт (напр. 65000) mov cx,0FDE8h ;По адресу памяти за нашей программой mov dx,offset Finish int 21h ;Файл в нашей памяти. Строка Hello, world находится в db ;в смещении 109h от начала программы hello, т.е. через 9 байт ;У нас она располагается тоже через 9 байт, но после конца (Finish equ $) ;Определим её настоящий адрес add dx,9h ;Переносим 15 букв c адреса смещения переменной New_phrase ;на новый адрес dx (конец нашей програмы + 9 байт) mov si,offset New_phrase mov di,dx mov cx,16 rep movsb mov dx,0h mov cx,0h mov ax,4200h int 21h mov ah,40h mov dx,offset Finish mov cx,25 int 21h ;Смотрим отладчик - файл прочтён и строка в памяти заменилась! ;Подпрограмма успешного вывода строки и выхода Message_ok: ;Сначала сохраним файл, восстановив bx mov bx,Handle mov ah,3Eh int 21h ;Выводим строку mov ah,9 mov dx,offset Mess_ok int 21h int 20h ;Подпрограмма безуспешного вывода строки и выхода Message_bad: mov ah,9 mov dx,offset Mess_bad int 21h int 20h ;Имя файла File_name db 'hello.com',0,'!$' ;Успешное сообщение Mess_ok db 'Файл обновлён. Всем спасибо.$' ;Плохое сообщение Mess_bad db 'Файл не найден. Поместите hello.com в каталог с программой.$' ;Определяем переменную Handle dw 0FFFFh ;Новая фраза, которая заменяет Hello, world New_phrase db 'Goodbye, world!$' ;Переменная для вычисления длины файла Finish equ $ CSEG ends end begin Сейчас это, конечно, бессмысленно. Но что, если с читаемым файлом проводится (в памяти) множество других операций, а потом требуется его записать - мой алгоритм верен?