Сглобяване Променете съдържанието на файла

След като прочета байт от файл в асемблиране, текущата файлова позиция се актуализира. Как мога да искам да променя този байт и след това да го запиша във файла на същата позиция, от която го чета? Работя в 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. Маркирането му помага на другите да го намерят.   -  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. На английски дръжка е нещо, с което можете да отворите врата например. Обслужващ е човек, който се занимава с чанти на летището, или функция, която обработва прекъсвания, или нещо подобно. (BTW, хубав отговор, това е хубаво и ясно с добри коментари, а не куп ненужен код, за да направите това част от цяла програма.) - 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