Сборка Изменить содержимое файла

После того, как я прочитал байт из файла в сборке, текущая позиция в файле обновляется. Как я могу изменить этот байт, а затем записать его в файл в той же позиции, из которой я его прочитал? Я работаю в tasm на x8086

READ_LOOP:
    MOV AH,3FH
    MOV BX, HANDLE
    MOV CX, 1
    LEA DX, BUFFER
    INT 21H
    INC SI
    ;if no byte was read we reached the end of file or an error occured
    CMP AL, 1
    JB EOF_END_ERR

    ;write the read content to output
    ;MOV AH, 02H
    ;MOV DL, BUFFER
    ;INT 21H

    JMP ENCRYPTING
    JMP FINAL

ENCRYPTING:
    XOR AX,AX
    MOV DL, BUFFER[0]
    ADD DL, NUMBER[0]
    MOV TEMP, DL

    MOV AH, 42H
    MOV BX, HANDLE
    MOV CX,0FFFFH
    MOV DX, 0FFFFH
    MOV AL,1
    INT 21H

    XOR DX,DX
    MOV DL, 65
    MOV BX, HANDLE
    MOV CX,1
    MOV AH, 40H
    INT 21H

    JMP READ_LOOP

Я попытался с помощью приведенного выше кода просто добавить NUMBER[0] к коду ASCII прочитанного байта, а затем записать его обратно в файл. Но он не пишет то, что должен в файле


person Darius Bogdan    schedule 11.12.2017    source источник
comment
Используйте функцию 42h, чтобы переместить указатель файла назад.   -  person Jester    schedule 12.12.2017
comment
@Jester, и как я могу использовать его, чтобы вернуться с 1 байтом? Можете ли вы привести пример, пожалуйста?   -  person Darius Bogdan    schedule 12.12.2017
comment
Найдите документацию по нему в списке прерываний Ральфа Брауна: ctyme.com/intr/rb- 2799.htm   -  person Peter Cordes    schedule 12.12.2017
comment
Вы работаете в Windows? Какая версия? Системные вызовы различаются для разных операционных систем, и вам нужен системный вызов для доступа к файлам. Пожалуйста, отметьте свой вопрос соответствующим образом.   -  person Daniel H    schedule 12.12.2017
comment
@DanielH Я работаю над Windows 10 и использую dosbox   -  person Darius Bogdan    schedule 12.12.2017
comment
Итак, вы используете системные вызовы DOS. (DOSBOX в Win10 такой же, как DOSBOX в Linux; все, что имеет значение, — это устаревшая среда DOS, которую он эмулирует.) Если вы пишете программу, которая еще не устарела, она может работать изначально в современных основных ОС с использованием системы, специфичной для ОС. звонки. (С другим набором системных вызовов, чем предоставляет DOS, а также с другими способами их вызова.)   -  person Peter Cordes    schedule 12.12.2017
comment
@DanielH: Использование int 21h означает, что это 16-битная программа для DOS, поэтому доступны только сервисные функции DOS и BIOS.   -  person Peter Cordes    schedule 12.12.2017
comment
Мой код работает отлично, я только что проверил. :)   -  person Ahtisham    schedule 12.12.2017
comment
@PeterCordes Вот почему я попросил пометить его. Я знал, что не могу ответить на этот вопрос, потому что я не использовал эту среду, но я думал, что Windows все еще использует int 21h. Пометка dos помогает другим найти его.   -  person Daniel H    schedule 12.12.2017
comment
@PeterCordes Я знал, что это, вероятно, не лучший способ даже в Windows, но я думал, что он все еще поддерживается.   -  person Daniel H    schedule 12.12.2017


Ответы (1)


Для этого вы можете использовать сервис AH=42h. После того, как вы прочитали байт из файла, указатель файла будет обновлен. Теперь, чтобы заменить предыдущий прочитанный байт в файле на что-то другое, вам нужно сначала переместить указатель файла на один байт назад (так, чтобы он указывал на байт, который вы хотите заменить), и это можно сделать с помощью следующего кода:

Код для перемещения указателя файла на один байт назад от его текущей позиции:

    mov al, 1        ; relative to current file position
    mov ah, 42h      ; service for seeking file pointer
    mov bx, handle
    mov cx, -1       ; upper half of lseek 32-bit offset (cx:dx)
    mov dx, -1       ; moves file pointer one byte backwards (This is important)
    int 21h   

После выполнения вышеуказанного кода вы теперь можете перезаписать байт новым байтом, и это можно сделать с помощью следующего кода:

Код для записи с текущей позиции указателя файла:

    mov ah, 40h          ; service for writing to a file
    mov bx, handle    
    mov cx, 1            ; number of bytes to write
    mov dx, offset char  ; buffer that holds the new character to be written
    int 21h

Чтобы узнать больше о работе с файлами, перейдите здесь.

person Ahtisham    schedule 12.12.2017
comment
У меня это не работает, только если я добавляю cx, 0ffffh и dx 0ffffh, потому что это -1 в C2, я думаю, что моя проблема была в том, что я не указал смещение в dx - person Darius Bogdan; 12.12.2017
comment
Это handle (как в дескрипторе файла), а не handler. По-английски ручка — это то, чем можно, например, открыть дверь. Обработчик — это человек, который обрабатывает сумки в аэропорту, или функция, которая обрабатывает прерывания, или что-то в этом роде. (Кстати, хороший ответ, он хороший и понятный, с хорошими комментариями, а не кучей ненужного кода, чтобы сделать эту часть целой программы.) - person Peter Cordes; 12.12.2017
comment
@dbogdan Почему вы отредактировали свой вопрос, чтобы задать другой? это неправильно, вы должны опубликовать отдельный вопрос для этого. Вернитесь к предыдущему вопросу и разместите новый вопрос отдельно. - person Ahtisham; 12.12.2017
comment
@dbogdan: хороший улов, исправил этот ответ, чтобы передать смещение со знаком в CX: DX. Re: ваше редактирование вопроса: ваш код не работает, потому что вы используете ah=40h/ int 21h неправильно. dx должен указывать на байты в памяти. Вы вызываете его с помощью DX=65 (и байт ptr [ds:65], вероятно, содержит мусор или ноль). Прочитайте этот ответ еще раз, это все еще правильный ответ. - person Peter Cordes; 12.12.2017
comment
@Ahtisham извините за редактирование вопроса, я новичок в stackoverflow и точно не знал, что мне делать, и спасибо за ответ. - person Darius Bogdan; 12.12.2017