AT & T - чтение файла - PullRequest
       26

AT & T - чтение файла

0 голосов
/ 24 ноября 2018

Я пытаюсь прочитать (как минимум) первую строку файла.Я использую системные вызовы для открытия и закрытия файла, но, похоже, у меня проблема с чтением содержимого из файла, потому что результатом является просто какой-то неизвестный символ../code

1 Ответ

0 голосов
/ 24 ноября 2018

Есть три ошибки:

Во-первых, вы сохраняете от eax до fd, как если бы fd имел длину 4 байта, но на самом деле это всего 1 байт.Затем вы вводите адрес fd в ebx, а не значение, загруженное из fd.Это дает некоторый случайный указатель на системный вызов, который, конечно, является неверным дескриптором файла.

Обратите внимание, что добавление правильной обработки ошибок позволило бы избежать по крайней мере второй проблемы.


Кроме тогоКак сказал Wumpus Q. Wumbley, вы не должны хранить файловый дескриптор в одном байте, так как его значение может превышать 255. Чтобы исправить обе проблемы, сначала сделайте fd 4-байтовое количество, выделив его пространство с помощью .int:

fd: .int 0

Это сразу исправляет первую проблему.Чтобы устранить вторую проблему, загрузите ebx из fd, а не $fd:

mov fd, %ebx

Последние ошибки находятся в блоке «print», где вы выполняете movl $fd,%ecx и movl $len, %edx.Это эквивалентно C, как write(1, &fd, &len).(Снова используя адрес len в качестве длины вместо загрузки из памяти).И вы, вероятно, хотите передать адрес buf (где вы читаете данные файла), а не fd, где вы сохранили целое число (не ASCII).Итак, вы хотите write(1, buf, len), а не write(1, &fd, len).

. Или лучше, вы должны использовать возвращаемое значение read в качестве длины для write, если это не код ошибки.Вы не хотите писать () байты-заполнители.Но если вы это сделаете, вы можете сделать len константой времени сборки вместо того, чтобы хранить ее в памяти.Используйте .equ, чтобы ассемблер вычислял длину буфера во время сборки, чтобы вы могли использовать mov $len, %edx


Обратите внимание, что после каждого системного вызова вы должны проверять, был ли системный вызов успешным.Вы можете сделать это, проверив, является ли результат отрицательным (строго говоря, отрицательным и его абсолютное значение меньше 4096).Если это так, произошла ошибка, и код ошибки является отрицательным результатом.Если вы обработаете все свои ошибки, очень легко увидеть, где и почему произошла ошибка вашей программы.

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

...