Olej писал(а):Из недостатков (не этого автора, потому как "нельзя объять необъятное" - но то, что хотелось бы видеть):
1. описывается ассемблер исключительно для Inteel x86, хотя AT&T/GAS покрывают куда более широкий перечень платформ процессорных;
2. описываются только IA-32 процессоры, про IA-64 ни слова, хотя там даже регистры будут по-другому записываться: %rax вместо %eax, а для AMD_64 даже число и назначение регистров будет другое, чем у Intel IA-64.
Интересная тема. Вот как раз может быть это замечание послужит поводом расрыть следующий вопрос. Читал главу из вашей книги
"Библиотечный и системный вызов из процесса" -
http://rus-linux.net/MyLDP/BOOKS/Moduli ... -02.html#1, и решил разобрать пример (mp.c) дабы освежить в памяти синтаксис Inline Assembler. После запуска программы пришёл в замешательство. Вывод был неожиданным:
getpid return : -14
string for write length = 23
Что удивило - ладно пусть программа завершается неожиданно, но почему нет сообщений об ошибке? Взял её strace'ом - вывод натолкнул на размышления:
getpid() = -1 EFAULT (Bad address)
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fcc25c77000
write(1, "getpid return : -14\n", 20getpid return : -14
) = 20
write(1, "string for write length = 23\n", 29string for write length = 23
) = 29
write(1, 0x1, 23 <unfinished ... exit status 1>
Т.е. в первом случае (getpid) - -1 EFAULT (Bad address), во втором (write) - unfinished ... exit status 1. Смутило ещё значение второго аргумента в write (0x1)....
Вобщем, гугл как всегда знает всё. Выяснилось, что у x86 и x86_64 (моя рабочая машина на которой я выполнял код) разные механизмы системного вызова.
Пришлось изменить участки кода с Inline Assembler:
например
Код: Выделить всё
int write_call( int fd, const char* str, int len ) {
long __res;
__asm__ volatile ( "int $0x80":
"=a" (__res):"0"(__NR_write),"b"((long)(fd)),"c"((long)(str)),"d"((long)(len)) );
return (int) __res;
}
изменил на
Код: Выделить всё
int write_call( int fd, const char* str, int len ) {
long __res = 0;
__asm__ __volatile__ (
"syscall":
"=a" (__res):
"a"(__NR_write),"D"((long)(fd)),"S"((long)(str)),"d"((long)(len))
);
return (int) __res;
}
Вопрос решён, но в голове остался сумбур в виде кучи вопросов. Олег, вы как то можете осветить эту тему (касательно этих механизмов), или ссылкой кинуть где данный вопрос раскрыт.