Добавление в конец текстового файла в сборке

У меня есть код TASM, и он не добавляет новую строку, когда я снова запускаю программу. Я хотел бы поблагодарить us2012 за помощь в достижении этого "состояния".

; This example program creates a file and then writes to it.
.model small
.stack

.data 
CR equ 13
LF equ 10

StartMessage DB "This program creates a file called NEW.TXT"
         DB ,"on the C drive.$"

EndMessage DB CR,LF,"File create OK, look at file to"
       DB ,"be sure.$"

WriteMessage  DB "An error has occurred (WRITING)$"
OpenMessage   DB "An error has occurred (OPENING)$"
CreateMessage DB "An error has occurred (CREATING)$"

WriteMe  DB "HELLO, THIS IS A TEST, HAS IT WORKED?",0
FileName DB "new.txt",0 ; name of file to open 
Handle   DW ?   ; to store file handle 

.code 
START:
mov ax,@data    ; base address of data segment
mov ds,ax   ; put it in ds
mov dx,offset StartMessage 
mov ah,09h 
int 21h 

mov si,offset FileName  ; put offset of filename in dx 
xor cx,cx       ; clear cx - make ordinary file
mov ah,6Ch      ; function 3Ch - create a file
mov al, 0
int 21h         ; call DOS service
mov bx, Handle
xor cx, cx
xor dx, dx
mov ah, 42h
mov al, 02h
int 21h


jc CreateError      ; jump if there is an error



mov si,offset FileName  ; put offset of filename in dx
mov al,2        ; access mode -read and write
mov ah,3Dh      ; function 3Dh - open the file
int 21h         ; call dos service



jc OpenError        ; jump if there is an error



mov Handle,ax       ; save value of handle 
mov bx, Handle
xor cx, cx
xor dx, dx
mov ah, 42h
mov al, 02h
int 21h



mov dx,offset WriteMe   ; address of information to write 
mov bx,Handle       ; file handle for file
mov cx,38       ; 38 bytes to be written
mov ah,40h      ; function 40h - write to file
int 21h         ; call dos service

jc WriteError       ; jump if there is an error
cmp ax,cx       ; was all the data written?
jne WriteError      ; no it wasn't - error!

mov bx,Handle       ; put file handle in bx 
mov ah,3Eh      ; function 3Eh - close a file
int 21h         ; call dos service

mov dx,offset EndMessage 
mov ah,09h 
int 21h 

ReturnToDOS:

mov ax,4C00h        ; terminate program 
int 21h 

WriteError:
mov dx,offset WriteMessage 
jmp EndError

OpenError:
mov dx,offset OpenMessage 
jmp EndError

CreateError:
mov dx,offset CreateMessage 

EndError:
mov ah,09h 
int 21h 
mov ax,4C01h 
int 21h 

END START

Если я использую 3Ch, программа работает, но не добавляется в конец файла. Используя 6Ch вместо 3Ch, это означает, что существующий файл не обрезается до ноль байтов, но всякий раз, когда я запускаю код, возникает ошибка при создании файла (файл не создается). Пожалуйста, помогите мне исправить код. Большое спасибо!

ИЗМЕНИТЬ 2:

; This example program creates a file and then writes to it.
.model small
.stack

.data 
CR equ 13
LF equ 10

StartMessage DB "This program creates a file called NEW.TXT"
         DB ,"on the C drive.$"

EndMessage DB CR,LF,"File create OK, look at file to"
       DB ,"be sure.$"

WriteMessage  DB "An error has occurred (WRITING)$"
OpenMessage   DB "An error has occurred (OPENING)$"
CreateMessage DB "An error has occurred (CREATING)$"

WriteMe  DB "HELLO, THIS IS A TEST, HAS IT WORKED?",0
FileName DB "new3.txt",0 ; name of file to open 
Handle   DW ?   ; to store file handle 

.code 
START:
mov ax,@data    ; base address of data segment
mov ds,ax   ; put it in ds
mov dx,offset StartMessage 
mov ah,09h 
int 21h 

mov si, offset FileName     ; put offset of filename in dx 
xor cx,cx       ; clear cx - make ordinary file
mov ah,6Ch      ; function 3Ch - create a file
mov bx, 3
mov dx, 12h
int 21h         ; call DOS service

jc CreateError      ; jump if there is an error

mov ah,3Eh      ; function 3Eh - close a file
int 21h         ; call dos service


mov dx, offset FileName     ; put offset of filename in dx
mov al,2        ; access mode -read and write
mov ah,3Dh      ; function 3Dh - open the file
int 21h         ; call dos service

jc OpenError        ; jump if there is an error

mov Handle,ax       ; save value of handle
mov bx, Handle
xor cx, cx
xor dx, dx
mov ah, 42h
mov al, 02h
int 21h

mov dx,offset WriteMe   ; address of information to write 
mov bx,Handle       ; file handle for file
mov cx,38       ; 38 bytes to be written
mov ah,40h      ; function 40h - write to file
int 21h         ; call dos service

jc WriteError       ; jump if there is an error
cmp ax,cx       ; was all the data written?
jne WriteError      ; no it wasn't - error!

mov bx,Handle       ; put file handle in bx 
mov ah,3Eh      ; function 3Eh - close a file
int 21h         ; call dos service

mov dx,offset EndMessage 
mov ah,09h 
int 21h 

ReturnToDOS:

mov ax,4C00h        ; terminate program 
int 21h 

WriteError:
mov dx,offset WriteMessage 
jmp EndError

OpenError:
mov dx,offset OpenMessage 
jmp EndError

CreateError:
mov dx,offset CreateMessage 

EndError:
mov ah,09h 
int 21h 
mov ax,4C01h 
int 21h 

END START

person Merlin Teige    schedule 31.03.2013    source источник


Ответы (1)


Посмотрите на эту часть:

mov dx,offset FileName  ; put offset of filename in dx 
xor cx,cx       ; clear cx - make ordinary file
mov ah,6Ch      ; function 3Ch - create a file
mov al, 0
int 21h         ; call DOS service

и в соответствующей документации:

AX = 6C00h
BL = open mode as in AL for normal open (see also AH=3Dh)
...
BH = flags
...
CX = create attribute (see #01769).
DL = action if file exists/does not exist (see #01770).
DH = 00h (reserved).
DS:SI -> ASCIZ file name

Return:
CF set on error AX = error code (see #01680 at AH=59h/BX=0000h)
CF clear if successful AX = file handle
CX = status (see #01768) 

Функция ожидает, что si, а не dx будет иметь смещение имени файла.

Вы не устанавливаете bx.

Вы не устанавливаете dx.

Вы не проверяете ошибки.

Вы не сохраняете дескриптор файла.

Посмотрите на эту часть:

mov bx, Handle
xor cx, cx
xor dx, dx
mov ah, 42h
mov al, 02h
int 21h

Handle на данный момент не инициализирован, потому что вы никогда не сохраняли дескриптор в эту переменную.

Теперь вот:

mov dx,offset FileName  ; put offset of filename in dx
mov al,2        ; access mode -read and write
mov ah,3Dh      ; function 3Dh - open the file
int 21h         ; call dos service

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

person Alexey Frunze    schedule 31.03.2013
comment
Спасибо, но, честно говоря, я не очень понимаю. Теперь я установил BX равным 2 (режим доступа для чтения/записи) и DX равным 3 (поведение существования файла) (stanislavs.org/helppc/int_21-6c.html) Я заменил DX на SI (в смещении имени файла), но при открытии файла возникла ошибка. Что касается неинициализированного Handle, я поместил mov ax, Handle перед mov bx,Handle. Но все равно ошибка. Программа действительно работает, если я использую 3Ch, и проблема в том, что она не добавляется. Пожалуйста, помогите мне, спасибо. - person Merlin Teige; 31.03.2013
comment
Пожалуйста, смотрите редактирование в моем вопросе. Это то, что я сделал, но из-за условий jc в коде он говорит, что при создании произошла ошибка. - person Merlin Teige; 31.03.2013
comment
Я бы установил BX=3 (чтение+запись) вместо BX=2 (только чтение). Кроме того, DX=3 недопустимо, оно не указано в таблице как допустимое значение. Вместо этого попробуйте 12H. И вы все еще повторно открываете файл, не закрыв его предварительно. - person Alexey Frunze; 31.03.2013
comment
Большое спасибо! Вместо si следует использовать dx, потому что он не добавляется всякий раз, когда я использую si. - person Merlin Teige; 31.03.2013
comment
Извините за BX=3, похоже, BX=2 был прав. Однако все 3 ссылки, которые я знаю, говорят, что функция 6Ch принимает смещение имени в SI. - person Alexey Frunze; 31.03.2013