2013-02-08 2 views
1

Я пытаюсь понять, как использовать указатель в сборке. Читая некоторые учебники по интернелю, я думаю, имел некоторые концепции. Но когда я собираюсь попробовать, это сработало. Ниже некоторые попытки перевести C в ASM.Указатели на языке ассемблера

C

const char *s = "foo"; 
unsigned z = *(unsigned*)s; 
if(!(z & 0xFF)) 
do_something(); 
if(!(z & 0xFFFF)) 
do_b_something(); 

(здесь не полный код, но это слово-чек, thefore, есть еще два stmts, который проверяет 0xFF0000,0xF000000 центров соответственно

ASM:.

mov ebp,str 
mov eax,ebp 

mov eax,[eax] 
and eax,0xFF 
cmp eax,0 
je etc 

mov eax,[eax] 
and eax,0xFFFF 
cmp eax,0 
je etc 

Он возвращает ошибку сего.

И попытка:

mov eax,dword ptr [eax] 

, который генерируется компилятором GCC и вы можете увидеть его в некоторых других сборок кода, возвращает

invalid symbol

на FASM ассемблере. FASM на самом деле не поддерживается, или я что-то упускаю?

+0

'dword ptr' необходим MASM и не более того. Просто используйте простые скобки. Сег-ошибка, вероятно, связана с использованием 'eax' в качестве указателя после его уничтожения. tip: use 'test' – harold

+0

Я не говорю C - не могли бы вы дать какое-то объяснение, чего вы пытаетесь достичь? У меня такое ощущение, что в сборке это очень просто. – johnfound

ответ

1

Я думаю, что это то, что вы пытаетесь сделать:

mov ebp,str 
    mov eax,ebp 

    mov ebx,[eax] 
    test ebx,0xFF 
    jz low_byte_empty 

    do_something: 
     ; some code here... 

low_byte_empty: 
    test ebx,0xFFFF 
    jz low_word_empty 

    do_b_something: 
     ; some code here. 

low_word_empty: 

Объяснение:

Прежде всего, как JasonD уже упоминает в своем ответе, вы загружаете указатель eax, затем делает логический and, то вы используете результат все еще в eax для адресной памяти (некоторое смещение памяти в диапазоне 0x0 ... 0xFF).

Так что же не так в коде: вы не можете хранить в одном регистре как указатель на адрес памяти, так и значение в одно и то же время. Поэтому я решил загрузить значение от [eax] до ebx, вы также можете использовать некоторые другие 32-разрядные общие регистры (ecx, edx, esi, edi) в соответствии с вашими потребностями.

Затем вам не нужно использовать cmp, чтобы проверить, не зарегистрирован ли регистр, потому что все cmp делает то, что он вычитает и устанавливает флаги. Но ZF (флаг нуля) уже установлен and, поэтому cmp здесь абсолютно не нужен. Тогда, поскольку cmpне нужен здесь, и нам тоже не нужен результат, мы хотим обновить флаги, лучше использовать test.test делает то же самое логическое И как and делает, с той лишь разницей, что test не сохраняет результат, он только обновляет флаги.

+0

Действительно! Мне не нужен cmp. «And» изменяет значение адресата, и я забыл его в течение определенного периода времени, поэтому я никогда не получу ожидаемый результат! ошибка EAX, которую я решил раньше. Огромное спасибо. –

+0

Вы также можете выжать дополнительную производительность и байты из этого ответа, отметив, что тест ebx, 0xff совпадает с тестом bl, bl, и этот тест ebx, 0xffff совпадает с тестом bx, bx. Наконец, вы можете использовать регистр, например ECX или EDX, а не EBX, потому что EBX обычно должен быть сохранен над вызовом функции. – SecurityMatt

1

Не совсем понятно, что вы пытаетесь сделать в исходном коде - не выглядит правильным.

Однако это:

mov eax,[eax] 
and eax,0xFF 
cmp eax,0 
je etc 

mov eax,[eax] 

Не будет работать. Вы перезаписываете содержимое EAX со значением, хранящимся по адресу в EAX, манипулируя этим значением, а затем пытаетесь перезагрузить его после ветки без восстановления исходного указателя.

+0

Большое спасибо. –

1

Следующий вариант проще, меньше, быстрее и использует только один регистр.

mov eax, str 
    mov eax,[eax] 

    test al, al 
    jz low_byte_empty 

do_something_byte: 
    ; some code here... 

low_byte_empty: 
    test ah, ah 
    jz low_word_empty   

do_something_word: 
    ; some code here 

low_word_empty: