asm gcc
Сделай objdump и посмотри, в какой момент чето-там
Вот лучше gcc -s (показываю кусок кода, относящийся к делу):
movl $0, -8(%ebp) //записываем ноль по адресу (%ebp-8локальная переменная esp = 0)
movl $127, %eax // записываем 127 в регистр %eax (127 - это BIT_MAS -1)
#APP
andl %esp,%eax //делаем операцию andl между %esp и %eax (!) и записываем результат в %eax!
#NO_APP
movl %eax, -8(%ebp) //записываем полученный результат в переменную esp
movl -8(%ebp %eax // так сделал gcc
movl %eax, 4(%esp) // сохраняем регистр %eax
movl $.LC0, (%esp) // кладем на стек строчку для распечатки
call printf // зовем функцию printf
Вопрос остается, почему делают andl между %esp и (BIT_MASK -1 )?
В сишном же фале написано делать "andl %%esp,%0", а порядковый номер 0 имеет переменная esp.
%%esp это регистр а не переменная, она просто случайно так-же называется.
andl %%esp, %0 , ведь %0 - это переменная esp, почему происходит так, что делается andl c (BIT_MASK-1)?
http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.h...
Matching(Digit) constraints
In some cases, a single variable may serve as both the input and the output operand. Such cases may be specified in "asm" by using matching constraints.
asm ("incl %0" :"=a"(var):"0"(var;
We saw similar examples in operands subsection also. In this example for matching constraints, the register %eax is used as both the input and the output variable. var input is read to %eax and updated %eax is stored in var again after increment. "0" here specifies the same constraint as the 0th output variable. That is, it specifies that the output instance of var should be stored in %eax only. This constraint can be used:
In cases where input is read from a variable or the variable is modified and modification is written back to the same variable.
In cases where separate instances of input and output operands are not necessary.
The most important effect of using matching restraints is that they lead to the efficient use of available registers.
В приведенном тобой примере все ясно
input операнд - переменная var
output операнд - переменная var
Поэтому %0 ссылается на одну и ту же переменную.
В моем примере
input operand - BIT_MASK-1
output операнд - переменная esp
%0 - переменная esp
%1 - выражение BIT_MASK-1
Я не понимаю
P.S. Почему это код работает и, как я писал в первом посте, если ставить "=r" (esp) : "r" (BIT_MASK - 1) ?
По мне, так нужно писать
#define BIT_MASK 128
long esp = 0;
__asm__ ("andl %%esp,%1 " :
"=r" (esp) : "0" (BIT_MASK - 1;
printf("esp = %lX\n", esp);
ты надеюсь понимаешь чем отличаются input/output операнды?
в обчем читай доку и не ищи тут логики, оно должно просто работать =)
Output операнды - это переменные/выражения сишного кода, которые будут изменяться благодаря ассемблерным инструкциям.
Свой пример я могу подправить
#define BIT_MASK 128
long esp = 0;
__asm__ ("andl %%esp,%1\n\t"
"movl %1,%0" :
"=r" (esp) : "0" (BIT_MASK - 1;
printf("esp = %lX\n", esp);
Но
Почему это код работает и, как я писал в первом посте, если ставить "=r" (esp) : "r" (BIT_MASK - 1) ?
И где в приведенном тобой отрывке из доки описан мой случай?
вход и выход мапится на один регистр, куда уж понятнее?
где сказано, что следующая строка должна мапить все на один регистр
"=r" (esp) : "r" (BIT_MASK - 1)?
читать из регистра у кторого ты не указал начального значения?
скорее всего корректность оно не проверяет а лепит что попало.
У какого регистра не указано начальное значение?
регистр esp - регистр стека
"=r" - означает что выходное значение сохранить в каком-либо регистре, gcc это делает (см. строчку "movl -8(%ebp %eax // так сделал gcc" )
"r" (BIT_MASK-1) означает, что входной параметр сначала кладется в регистр (см. строчку "movl $127, %eax" ).
Поясни, пожалуйста, что ты имеешь в виду, поскольку мы далеко уже ушли от начального вопроса.
почитай всё-таки документацию, я думаю её можно найти в локальной сети, где-нить в сырцах gcc.
Оставить комментарий
kataich
У меня нет интернета, поэтому прошу посмотреть на следующий кусочек кода:output операнд - переменная esp; "=r"говорит gcc, что этот операнд wite-only и его значение сохранить в регистре.
input операнд - (BIT_MASK - 1 далее я не уверен, но, по-моему, "0" означает, что использовать такой же атрибут, как и у операнда номер 0, в данном случае переменной esp (я не знаю как называются по-русски штуки, стоящие в кавычках)
Этот код показывает последние семь битов регистра %esp.
Объясните, пожалуйста, почему?
Ведь
"andl %%esp,%0" делает побитовое или с переменной esp, которой я придал значение НОЛЬ. В какой момент переменная esp становится равной (BIT_MASK -1)
P.S. Вместо "=r" (esp) : "0" (BIT_MASK - 1) ставил "=r" (esp) : "r" (BIT_MASK - 1) - результат тот же.