Здравствуйте. подскажите пожалуйста почему не читает из файла Код (Text): section .data fd dw 0 path db "./rabbit",0 section .bss buf resb 3 necx resd 1 section .text global _start _start: push path call open mov [fd], ax mov ecx, 10 labl: mov [necx], ecx push 3 push buf push word [fd] call read push buf push 3 call msg mov ecx, [necx] loop labl push word [fd] call close push 0 call exit exit: mov eax, 1 mov ebx, [esp+4] ;exit code int 80h ret msg: mov eax, 4 mov ebx, 1 mov ecx, [esp+8] ;ptr 2 string mov edx, [esp+4] ;nsymbols int 80h ret open: mov eax, 5 mov ecx, 0 mov edx, 0 mov ebx, [esp+4] ;ptr 2 path ret read: mov eax, 3 mov ebx, [esp+4] ;fd mov ecx, [esp+6] ;ptr 2 buf mov edx, [esp+10] ;count of bytes ret close: mov eax, 4 mov ebx, [esp+4] ;fd ret
Возможно, я тупой, но покажите мне вызов системной функции открытия файла? И да, для того, чтобы узнать, почему не происходит чтение, нужно проанализировать значение, возвращаемое функцией чтения.
Ну и вопросики у вас, товарищ. Даже не знаю, что и посоветовать. Ну фик его знает, я обычно в МСДНе смотрю, когда дело Виндовс касается. Если ДОС - тоже справочка имеется. Ну и для ЮНИКС наверняка должно быть. Откуда то же вы узнали про int 80? Вот там и значения ошибок должны быть. По идее, в регистре eax должны возвращаться.
там смотрел - нету смотрел в сишном мане но там понятно всё в константх которые определены в .h .c файлах которые я затруднился найти
Блин, ну действительно, не знаю, поискал в гугле - не находится. А, видимо, это связано с тем, что под линукс не очень-то программирование на ассемблере развито. Ну не знаю, ищи, где-то же должно быть. Может, кто-то здесь ссылочку подкинет? Я с линукс дело не имел, так что не знаю. А что вот эта строка значит: "./rabbit", 0 ? Почему одна точка? Это должно обозначать переход на каталог вверх? Тогда, вроде, две точки должно быть. Ну что можно посоветовать. Во-первых, файл для чтения помести в один каталог с твоей программой. Тогда будет "rabbit", 0 Во-вторых, программировать на ассемблере (да и на любом другом языке, наверное), не зная описания функций - дохлый номер. Ты ж даже не узнаешь, правильно сработал системный вызов или нет. Ну, а в третьих, если программа не работает, то сначала нужно определить, в каком месте неправильно. Вот ты задал вопрос - почему не читает. Сначала нужно исключить все возможные ошибки - то, что я с файлом для чтения советовал сделать, определить, открыт ли файл. Ну, в-общем, учись отлаживать программу. Честно говоря, это не тот вопрос, с которым стоит лезть на форум. Здесь ты лучше только узнай, где взять инфу по системным вызовам. Скачай пару книжек по программированию под линукс, что ли. На русском их немного. И разбирайся сам. В этой твоей программе сразу несколько ошибок: 1. Это то, что я про файл говорил. 2. push path call open Вместо call open подставь реализацию open. Это избавит тебя от возможных ошибок при работе со стеком. Естествено, при этом строки mov eax, 5 mov ecx, 0 mov edx, 0 mov ebx, [esp+4] ;ptr 2 path будут несколько другими. Если не понимаешь, почему, тоже не лезь на форум. Разберись лучше сам. Пока будешь вникать, заодно многие другие вещи узнаешь. Ну, в-общем, вот таким путём, извини за сумбурность изложения, удачи. Если надо, ссылочек на литературу могу накидать. А, ну и, конечно, начинать нужно с изучения ассемблера, если, конечно, ты с ним не знаком.
ragim open как сисколл возвращает неотрицательное число (файловый дескриптор) в случае успеха, и отрицательный код ошибки в случае провала. Коды ошибок можно найти в /usr/src/linux/include/asm-generic/errno-base.h. Там они положительные, но это не должно смущать, сисколлы, в случае ошибки делают что-то типа: Код (Text): return -EPERM;
Sasha7b9 . -- это текущая директория. Она необязательна в данном случае, но это не делает путь невалидным. Нахрена? Чтобы провоцировать ошибки типа "очепятка"? Чтобы код занимал больше байт? Чтобы потом, когда захочется чтобы open код ошибки клал бы в errno, пришлось бы выискивать в коде все вызовы open?
Код (Text): section .text global _start _start: push 0 ; O_RDONLY push filename ; call sys_open cmp eax, -1 je @@exit mov [fd], eax push 0x10000 push data push dword [fd] call sys_read cmp eax, -1 je @@exit push eax push data push 1 call sys_write @@exit: call sys_exit ; ------------- sys_open: mov eax, 5 mov ebx, [esp + 4] mov edx, [esp + 8] int 0x80 ret sys_read: mov eax, 3 mov ebx, [esp + 4] mov ecx, [esp + 8] mov edx, [esp + 12] int 0x80 ret sys_write: mov eax, 4 mov ebx, [esp + 4] mov ecx, [esp + 8] int 0x80 ret sys_exit: mov eax, 1 int 0x80 section .bss data resb (0x10000 + 1) section .data fd dd 0 filename db '/etc/fstab', 0 Компилировать: nasm -f elf readfile.asm ld -s -o readfile readfile.o Запускать: ./readfile Или такой вариант с strace: strace ./readfile
r90 У него используется функция 5 прерывания 80h, если я правильно понял. Ну, может это и одно и то же конечно, я не в курсе. Вы случайно не знаете, где найти описание прерывания 80h? Функции там, коды ошибок? r90 Да нет, ну я же написал. Вечно у меня проблемы с выражением мысли) Для отладки, чтобы убедиться, что всё сделано правильно. Потом конечно, оформить в виде функции. Не знаю, я так часто делаю - если не знаю, где ошибка, максимально упрощаю код, чтобы уменьшить число потенциальных проблем.
INT 0x80 - сервис системных вызовов ядра Linux Смотрите тут: Код (Text): arch/x86/kernel/syscall_table_32.S include/asm-generic/errno.h include/asm-generic/errno-base.h