Встроенная сборка сложнее, чем кажется. Попытка кратко покрыть проблемы для GCC:
- Если он изменяет регистры процессора, необходимо поместить эти регистры в список дубликатов. Важно отметить, что список clobber должен содержать ALL регистров, которые вы изменили напрямую (читайте явно ) или косвенно (читайте неявно );
- Для усиления (1) условные и математические операции также изменяют регистры, более известные как флаги состояния (ноль, перенос, переполнение и т. Д.), Поэтому вы должны сообщить об этом, добавив "cc" к список клоберов;
- Добавить «память» , если она изменяет различные (читаемые случайным образом) позиции в памяти;
- Добавьте ключевое слово volatile , если оно изменяет память, которая не упоминается в аргументах ввода / вывода;
Тогда ваш код становится:
asm("movl 0x1C(%%esp), %0;"
: "=r" (value)
: /* no inputs :) */
/* no modified registers */
);
Выходной аргумент не обязательно должен быть в списке clobber, потому что GCC уже знает, что он будет изменен.
В качестве альтернативы, поскольку все, что вам нужно, это значение регистра ESP, вы можете избежать всей этой боли:
register int esp asm("esp");
esp += 0x1C;
Возможно, это не решит вашу проблему, но это путь. Для справки отметьте , , , и , .
.