2017-02-09 13 views
0

Я потратил 2 часа на поиски в Интернете, но безрезультатно --- на сборке не так много руководств начального уровня, и курс, который я принимаю прямо сейчас, не очень хорошо разбирается в объяснении некоторых вещей.Как отличный пример от примера (% rip)?

В любом случае; Я пытался работать с SSE и пытался сравнить два double с помощью команды comisd. Я потратил много времени, чтобы понять, как жестко закодировать нецелую константа (назовет его example, он объявлен как

example: 
    .long 3794832442 
    .long 1044740494 

); но после того, как я это сделал, я не смог заставить его работать - «несоответствие типа операнда». Я обратился к переводчику C-to-assembly и выяснил, что вместо моего comisd $example, %xmm0 он использовал comisd example(%rip), %xmm0, и он оказался работать. Теперь я не понимаю, как это работает и как они отличаются друг от друга?

+2

'' 'немедленное, что не может работать. Пример 'comisd,% xmm0' работал бы. – Jester

+0

Теоретически 'example equ ((1044740494 << 32) +3794832442)' будет правильной вещью для '$ example', но нет инструкции' comisd', принимающей аргумент 'imm64', допустимы только' xmm/m64', поэтому ваш правильное определение (значение, хранящееся в памяти, а символ «пример» - это метка, указывающая на его адрес), и необходимость использования в инструкции должна быть исправлена. – Ped7g

ответ

1

$example - это просто абсолютный адрес этой переменной - это не означает доступ к памяти.

Вы получаете «несоответствие типа операнда», потому что comisd не поддерживает непосредственный операнд. comisd example, %xmm0 (без $) работал бы, поскольку это ссылка на память.

example(%rip) использует режим адресной адресации ПК, введенный в x86-64, что делает код не зависящим от положения, поскольку вместо использования абсолютного адреса он использует смещение от текущего указателя инструкции.


На основании ответа Джонатон Рейнхарт.

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

  • Нет связанных вопросов^_^