сборка заказа по перекидной линии 32bit - PullRequest
0 голосов
/ 06 мая 2018

Мне нужно изменить порядок строк в файле и записать их в другой файл, но у меня есть некоторые проблемы. Я не могу написать в file2 по какой-то причине ... Любые советы и подсказки будут полезны, это моя первая проблема этого типа. Подсказка от моего учителя состояла в том, чтобы использовать fseek, и я использовал это, но я застрял.

пример:

входной файл1:

line1
line 2
line 3

желаемый выходной файл2:

line 3
line2
line 1

    .386
    .model flat, stdcall
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    ;includem biblioteci, si declaram ce functii vrem sa importam
    includelib msvcrt.lib
    extern exit: proc
    extern fopen:proc
    extern getc:proc
    extern fclose:proc
    extern printf:proc
    extern ftell:proc
    extern fseek:proc
    extern fscanf:proc
    extern fprintf: proc
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    ;declaram simbolul start ca public - de acolo incepe executia
    public start
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    ;sectiunile programului, date, respectiv cod
    .data
    ;aici declaram date
    s db 99 dup(0)
    read db "r",0
    write db "w",0
    nume db "fisier1.txt",0
    nume2 db "fisier2.txt",0
    seek_end dd 2
    format db "%s",0
    .code

    start:
        ;open first file to read
        push offset read
        push offset nume
        call fopen
        add esp,8
        mov esi,eax;save pointer of file

        ;open second file to write
        push offset write
        push offset nume2
        call fopen
        add esp,8
        mov edi,eax;save pointer of file

        ;find the end of file
        push seek_end
        push -1
        push esi
        call fseek
        add esp,12

        ;save in ecx current position
        push esi
        call ftell
        add esp,4
        mov ecx,eax

        et:
            push esi
            call getc
            add esp,4
            cmp eax,0ah;verify if isn't new line
            jne previous
            previous:
                ;move to the previous line
                push 1
                push -1
                push esi
                call fseek
                add esp,12
                jmp cont
            read_write:
                ;read the line in string s 
                push offset s
                push offset format
                push esi
                call fscanf
                add esp,12

                ;print string s in second file
                push offset s
                push offset format
                push edi
                call fprintf
                add esp,12

                jmp previous

        cont:
            dec ecx
            ;verify if isn't the beginning of file  
            cmp ecx,0
            jne et

        push 0
        call exit
    end start

1 Ответ

0 голосов
/ 07 мая 2018

Это определенно то, что я бы не написал на ассемблере ... Однако, чтобы выполнить эту работу, я сначала написал бы алгоритм на языке высокого уровня. Если вы можете заставить логику работать должным образом на языке более высокого уровня, вы можете заставить свою сборку работать.

in = fopen("source.txt", "r");
fseek(in, 0, SEEK_END);
size = ftell(in);
fseek(in, 0, SEEK_SET);
out = fopen("destination.txt", "w");
ftruncate(out, size);
fseek(out, 0, SEEK_END);
while(fgets(buf, sizeof(buf), in))
{
    len = strlen(buf);
    fseek(out, -len, SEEK_CUR);
    fwrite(out, 1, len, buf);
    fseek(out, -len, SEEK_CUR);
}

Эта функция имеет ограничение на размер строки, определяемое sizeof(buf), и в этой строке есть ошибка:

fgets() не возвращает строку с нулевым символом в конце, если он может прочитать sizeof(buf) байт.

Вот как, к сожалению, плохо работает библиотека C. Простое исправление этой ошибки:

buf[sizeof(buf) - 1] = '\0';
...
fgets(buf, sizeof(buf) - 1, in)

т.е. Вы помещаете '\0' в конец буфера и никогда не перезаписываете его. Поэтому, по крайней мере, вы никогда не переполняете свой буфер.

Теперь вам нужно преобразовать этот код на C в сборке.

Также сначала разберитесь в вашем алгоритме, прежде чем приступать к реальному кодированию.

Примечание: я не проверял ни на какие коды ошибок. Обработка ошибок - хорошая идея. (то есть, что если fopen("destination.txt"...) терпит неудачу?)

...