2016-10-05 4 views
1

Я пытаюсь сделать свой собственный системный вызов для 64-битной Linux-системы. но он продолжает говорить мне, что у меня плохой тип. Компилятор пытается косвенно обращаться к buf? У меня такое чувство, что я испортил свои входные ограничения. Мне просто нужен адрес buf по адресу %2.inline asm type несоответствие

ошибка:

test.c: Assembler messages: 
test.c:28: Error: operand type mismatch for `movq' 


static int myread(int fd, char *buf, int size) { 
    register int bytes; 

    asm(
    "movq $0, %%rax\n" 

    "movq %1, %%rdi\n" 
    "movq %2, %%rsi\n" 
    "movq %3, %%rdx\n" 
    "syscall\n" 

    "movq %%rax, %0" 

    : "=r" (bytes) 
    : "m" (fd), "m" (buf), "m" (size) 
    : "%rax", "%rdi", "%rsi", "%rdx" 
    ); 

    return bytes; 
} 
+1

Вы получите эти ошибки, если 'int' является 32-разрядным целым числом. – Mysticial

ответ

1

Как сказал Мистическая, ошибка несоответствия исходит из того, что вы используете movq (что для 64-битных значений) на 32-битных целых чисел (например, ФД и размер).

Но помимо этого, этот код действительно неэффективен и неточен (но опасно) испорчен. Может быть, что-то больше, как это:

static int myread(int fd, char *buf, int size) { 
    register int bytes; 

    asm(
     "syscall" 

    : "=a" (bytes) 
    : "D" (fd), "S" (buf), "d" (size), "0" (0) 
    : "rcx", "r11", "memory", "cc" 
    ); 

    return bytes; 
} 

Чтобы понять это, проверьте machine constraints для i386.

Обратите внимание, что syscalls clobber регистры rcx и r11. Если вы не сообщите компилятору, что вы меняете эти значения, это может привести к очень странным проблемам. И проблемы не будут происходить в syscall, но сто строк ниже по течению.

Я также собираюсь сделать шаг для НЕ использования встроенного asm. Я не уверен, почему вы не хотите просто использовать системные вызовы, но вы просто настраиваете себя на горе.

+0

Я пишу тривиальную программу оболочки только для академических целей. https://github.com/MrOutput/learning/blob/master/shell/shell.c также кажется, что gcc не может оптимизировать мой код, не испортив чего-то. В AMD64 abi я не мог найти информацию о том, какие регистры сбиты с помощью некоторых системных вызовов. Не могли бы вы указать мне в сторону обучения самостоятельно? Спасибо за ваше время! – Rafael

+0

aha Я просто нашел его в A.2.1 – Rafael

+0

Я нахожу, что изучение деталей низкого уровня действительно помогает мне лучше программировать на более высоких уровнях. Я считаю эти тривиальные программы очень полезными для меня. – Rafael

Смежные вопросы