2013-12-22 5 views
1

Давайте сделаем вид, что переменная a размещена по адресу 0xDEADBEEF, и ее значение равно 42. Как я могу сравнить значение a (42) с другим int?Сравнивая значение, указанное указателем

В настоящее время у меня есть (Intel синтаксис):

mov rax, 0xDEADBEEF; 
mov rdi, 1; 
cmp [rax], rdi; 

Является ли это правильно?

+0

Неудачник или отказ? –

+0

@KerrekSB нет, но он не делает то, что я ожидаю, и я не уверен, что ошибка из-за этого кода или из-за чего-то еще. – alexandernst

+0

Тестирование модулей :-) –

ответ

1

Маленькие процессоры endian (как и большинство современных настольных) упорядочивают значения в памяти назад. Например, если значение в 0xDEADBEEF является 42, иначе 0x0000002A, то он будет сохранен как

2A 00 00 00 

Вы можете заставить, сколько байтов команда cmp [rax], rdi; сравнивает, предваряя байт/слово/двойное. Например, в NASM

cmp BYTE [rax], rdi; 

бы сравнить только первый байт, на который указывает указатель rax.

Проверьте документацию ассемблера на точный синтаксис. Также проверьте, сколько байтов ваш ассемблер сравнивается с командой cmp по умолчанию.


Edit: Игнорирование все, что я написал выше.

С вашего вопроса отмечен x86-64 Я предполагаю, что ваша программа 64 бит.

rdi имеет длину 8 байт. Ваш код делает все правильно, если значение в 0xDEADBEEF составляет 8 байт, а также:

2A 00 00 00 00 00 00 00 

В противном случае, если только первые 4 или 2 или байты установлены для коррекции значения, ваша программа может или не может работать правильно. Например, если значение в 0xDEADBEEF длиной 4 байта, то она будет выглядеть следующим образом

2A 00 00 00 ?? ?? ?? ?? 

Остальная часть memooryy будет содержать какой-либо другой случайной информации. Ваша программа будет иметь худший вид ошибки - тот, который происходит случайным образом. Инструкция cmp по-прежнему будет сравнивать 8 байтов, так как rdi имеет длину 8 байтов.

И ответить на ваш комментарий к вопросу наводчика (так как я не имею привилегии комментировать):

mov rax, [0xDEADBEEF] 
cmp rax, 1 

такого же, как

mov rax, 0xDEADBEEF 
cmp [rax], 1 
+1

перемещение значения '' '0xDEADBEEF'' внутри rax сделает rax' '' 24 00 00 00 00 00 00'''. И перемещение 1 в rdi сделает rdi «01 00 00 00 00 00 00 00'''. Сравнение этих значений как слова, dword или qword должно возвращать тот же результат, правильно? – alexandernst

+1

@alexandernst Да, 'rax' будет указывать на' 2A 00 00 00 00 00 00 00'. Также в моем посте был тип, а вместо 2A - 24. Значения хранятся в натуральном порядке в регистрах, поэтому 'rdi' будет' 00 00 00 00 00 00 00 01'. Да, размер операндов не должен иметь значения - пренебрегайте моим оригинальным сообщением :) –

+0

Действительно, я думал о чем-то рыбном с этим 4bytes int в 8-байтовый регистр ... (потому что, да, 0xDEADBEEF указывает на int). Наверное, я должен переехать на eax. :) – alexandernst

-1

Вы mov ИНГ значения 0xDEADBEEF в rax, вместо этого вам необходимо L oad E ffective A ddress в rax

Не уверен в вашей Assembler, но в NASM:

lea rax, [SomeAddress] 

Или:

mov rax, [SomeAddress] 
+0

Почему? Я действительно хочу получить * значение * '' '0xDEADBEEF''' внутри' '' rax'''. Или я чего-то не хватает? – alexandernst

+0

В соответствии с тем, что вы сказали: «Давайте сделаем вид, что переменная a помещается в адрес 0xDEADBEEF, а значение« 42 », и ваш заголовок:« Сравнение значения, указанного указателем ». – Gunner

+0

Не '' 'mov rax, [0xDEADBEEF]' '' то же самое, что '' 'mov rax, 0xDEADBEEF''', а затем' '' cmp [rax], 1'''? – alexandernst

0

Какой ассемблер? Для газа, предполагая, что .intel_syntax noprefix:

cmp QWORD PTR ds:0xdeadbeef, 1 

Обратите внимание, что 0xdeadbeef будет знак продлен. Вы можете предпочесть быть явным и включить ff s, чтобы сделать это понятным.

Обычно вам не нужно указывать ds:, потому что вы будете ссылаться на метку, и ассемблер будет обрабатывать вещи. То есть:

cmp DWORD PTR [foo], 1 
    cmp DWORD PTR foo, 1  # same thing 
Смежные вопросы