Как считать информацию из текстового файла с помощью nasm на Linux?
Учу nasm на ОС Linux (Ubuntu 18.04). Получилось выести строку в терминал: вот код:
section .data
msg: db "Linux rules 4ever",0x0A,0
msglen equ $-msg
global _start
_start:
mov eax, 4
mov ebx, 1
mov ecx, msg
mov edx, msglen
int 0x80
mov eax, 1
mov ebx, 0
int 0x80
Компилирую командами:
nasm -f elf File.asm -o prog01.o
ld -m elf_i386 prog01.o -o prog01
Строка выводится в терминал. Теперь хочу усложнить задачу и вывести строку из файла .txt. Файл создал заранее через текстовый редактор nano в той же папке, где и файл .asm, вот код:
section .data
file: db "test.txt", 0
O_RDONLY equ 0
O_WRONLY equ 1
O_RDWR equ 2
O_CREATE equ 100o
O_TRUNC equ 1000o
O_APPEND equ 2000o
section .bss
descriptor resb 4
buffer resb 20
section .text
global _start
_start:
mov eax, 5
mov ebx, file
mov ecx, O_RDWR
mov edx, 2
int 0x80
mov [descriptor],eax
mov eax, 3
mov ebx, [descriptor]
mov ecx, [buffer]
mov edx, 20
int 80h ; Считали информацию из файла
mov eax, 4
mov ebx, 1
mov ecx, [buffer]
mov ebx, 20
int 0x80 ; "Записали" на экран
mov eax,6
mov ebx,[descriptor]
int 0x80 ;закрытие файла
; выход из программы
mov eax, 1
mov ebx, 0
int 0x80
Компилирую теми же командами только в файл prog02.o и prog02. Ошибок не выдает, но когда запускаю исполняемый файл, вывода текста не происходит, а терминал просто переводит каретку на новую строку. Помогите правильно считать иформацию из файла и вывести ее на экран.
Ответы (1 шт):
5 копеек про отладку
т.к. в программе ничего кроме системных вызовов по сути и нет, то для отладки оных удобно использовать утилиту strace, по сути в данном случае она сразу выдаст все ошибки:
$ strace ./prog02
execve("./prog02", ["./prog02"], 0x7ffd10a5da90 /* 125 vars */) = 0
strace: [ Process PID=11513 runs in 32 bit mode. ]
open("test.txt", O_RDWR) = 3
read(3, NULL, 20) = -1 EFAULT (Неправильный адрес)
write(20, NULL, 20) = -1 EBADF (Неправильный дескриптор файла)
close(3) = 0
exit(0) = ?
+++ exited with 0 +++
Конкретные ошибки
mov ecx, [buffer]
Здесь в ecx помещается содержимое, которое находится по адресу buffer, а должен помещаться сам адрес буфера. Сравни строчку со своей предыдущей программой.
mov ebx, 20 int 0x80 ; "Записали" на экран
Опечатка; размер должен помещаться в edx, а не ebx. Кроме того ты выводишь в stdout весь буфер, независимо от того, сколько было прочитано из файла.
mov eax, 5 mov ebx, file mov ecx, O_RDWR mov edx, 2 int 0x80
Т.к. O_CREAT не задан, то значение edx задавать не обязательно. Но если задаёшь, то стоит указывать что-то осмысленное, например 0777.