Почему сборка не кажется мне последовательной? - PullRequest
0 голосов
/ 12 октября 2010

Извлечено из визуальной студии:

    CheckPointer(pReceivePin,E_POINTER);
017D616D  cmp         dword ptr [ebp+0Ch],0 
017D6171  jne         CBasePin::Connect+4Dh (17D617Dh) 
017D6173  mov         eax,80004003h 
017D6178  jmp         CBasePin::Connect+1A7h (17D62D7h) 

Но фактическое определение:

#define CheckPointer(p,ret) {if((p)==NULL) return (ret);}

Хотя моя сборка не так хороша, я не вижу никакой связи между исходным кодом и asm.

Ответы [ 4 ]

3 голосов
/ 12 октября 2010

Вы упустили достаточно того, что в этом трудно быть уверенным, но часть, которая может быть отсортирована, выглядит разумно. NULL == 0, поэтому:

017D616D  cmp         dword ptr [ebp+0Ch],0               ; if [ebp+0ch] == 0
017D6171  jne         CBasePin::Connect+4Dh (17D617Dh)    ;     goto 172617dh
017D6173  mov         eax,80004003h                       ; else load 'ret'
017D6178  jmp         CBasePin::Connect+1A7h (17D62D7h)   ;     and return it.

Очевидная проблема в том, что вы не показали нам, что находится в 17D617Dh или 17D62D7h, поэтому мы не можем на самом деле догадаться, что на самом деле делается со значениями.

0 голосов
/ 12 октября 2010

Сборка выглядит отлично.

cmp dword ptr [ebp+0Ch],0 - это сравнение pReceivePin с NULL.pReceivePin - это локальная переменная внутри вашей функции, поэтому ее адрес является смещением относительно начала стекового фрейма функции.ebp содержит адрес начала кадра стека.0Ch - это смещение pReceivePin внутри фрейма стека.Все локальные переменные в вашей функции будут адресованы как [ebp + something], кроме параметров.Параметры обычно адресуются как [ebp - something].

mov eax,80004003h - это не что иное, как значение E_POINTER, помещенное в область «возвращаемого значения» функции (для этого используется регистр eax).1017 *

Финальный jmp отправляет управление на код эпилога текущей функции (CBasePin::Connect), который заканчивается командой ret (и «возвращает» текущее значение eax, т.е. E_POINTER)

Средняя jne чувствительна к коду сразу после вашего макроса, если pReceivePin не равно E_POINTER.

0 голосов
/ 12 октября 2010

Вам нужно предоставить больше контекста, но вполне возможно, что последняя строка переходит к завершающим частям функции CBasePin :: Connect, которая вскоре следует RET.Это вполне соответствует логике вашего макроса.Вторая строка переходит сразу после последней строки, если указатель не ноль (т. Е. Ноль).

0 голосов
/ 12 октября 2010

Скорее всего

 CheckPointer(pReceivePin,E_POINTER);
 017D616D  cmp         dword ptr [ebp+0Ch],0 
 017D6171  jne         CBasePin::Connect+4Dh (17D617Dh) 
 017D6173  mov         eax,80004003h 
 017D6178  jmp         CBasePin::Connect+1A7h (17D62D7h) 

pReceivePin находится по адресу, хранящемуся в стеке; обычно к нему обращаются через косвенное обращение, используя хранилище значений в ebp.

по сравнению с нулем, и если оно равно нулю (jne не срабатывает), фактическое значение E_POINTER перемещается в eax (eax используется для хранения возвращаемого значения функции) и управление передаетсяв эпилог функции, где выполняется очистка, а затем управление возвращается вызывающей стороне (инструкция ret).Если значение pReceivePin не равно нулю (jne действительно срабатывает), управление передается в другое место, где сохраняется код, который был после CheckPointer, и этот код затем выполняется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...