2015-10-19 8 views
0

Я написал программу ac, которая использует библиотеку WINAPI (в частности, WSA-Sockets), и вместо компиляции исходного кода попросил компилятор испустить источник сборки вместо этого изучить, как он работает на более низком уровне.x86 WinAPI - Я не понимаю, как некоторые аргументы функции ссылаются в моей программе

При пересечении этой строки ниже я заметил в сборке, что нет ссылки на первый аргумент моей функции WINAPI. Функция MAKEWORD в WSAStartup.

Что на самом деле происходит здесь? Там нет ссылки в моей сборке кода MAKEWORD, но намек на толчке 514.


; source code :  if (WSAStartup(MAKEWORD(2,2),&wsa) != 0) 

    lea  eax, DWORD PTR _wsa$[ebp] ;_wsa$ is second arg 
    push eax 
    push 514   ; 00000202H ??? 
    call DWORD PTR [email protected] 
    test eax, eax 
    je SHORT [email protected] 

Примечание: Функция WSAStartup инициирует использование Winsock DLL процессом.

я могу предоставить больше информации, если это необходимо

+0

'MAKEWORD' просто компилятор макросъемки (не функция), которая упаковывает байты в WORD - вы должны быть в состоянии найти определение в коллекции заголовка компилятора где-то (это, вероятно, выглядит примерно так:' #define MAKEWORD (x, y) (x << 8 + y) '. Посмотрите на байты в значении, которое нажимается на стек - 0x02, 0x02. –

+0

' lea' - это «загружаемый эффективный адрес», который загружает адрес вычисленный из 'DWORD PTR _wsa $ [ebp]' в 'eax',' 514' выглядит как syscall для 'ioctl' (32-разрядный). Оба' eax' и '514' помещаются в стек, а затем похоже, что вызов выполняется для выполнения вашего запроса 'ioctl', с возвратом в' eax', проверенным после вызова. –

+1

@ DavidC.Rankin: Ther e не является кодом IOCTL. Там также нет syscall. '514' - это первый аргумент, переданный в [WSAStartup] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms742213.aspx) (нажата на стек справа налево). Syscall происходит, когда код вызывает 'DWORD PTR __imp__WSAStartup @ 8'. «Test eax, eax», скорее всего, является сборкой версии 'if'. – IInspectable

ответ

4

MAKEWORD является функцией, как макрос препроцессора, который определяется как

#define MAKEWORD(a, b) ((WORD)(((BYTE)(((DWORD_PTR)(a)) & 0xff)) | 
         ((WORD)((BYTE)(((DWORD_PTR)(b)) & 0xff))) << 8)) 

Так как вы используете его с константами времени компиляции (2 и 2) , компилятор может вычислить конечное значение, сдвинув второй аргумент 8 бит влево и добавив первый: 2 << 8 + 2. Результат: 512 + 2, значение 514, которое вы видите, попало в стек.

+0

Так есть ли какое-либо смысловое значение для помещения MAKEWORD (2,2) вместо 514? Или просто небольшая оптимизация? – BDillan

+0

@BDillan: Оптимизации вообще нет, это чистая семантика. Подумайте, кто-то читает ваш код, что передаст более значимую информацию: '514' или' MAKEWORD (2,2) '? Последнее упрощает просмотр, что вы хотите инициализировать * Версия 2.2 *. Компилятору все равно, какой из них вы используете. Полученные коды операций будут одинаковыми. – IInspectable

0
lea eax, DWORD PTR _wsa$[ebp]  ; eax = pointer to WSADATA structure 
push eax       ; set second argument = eax 
push 514       ; set first argument = version 2.2 
call DWORD PTR [email protected] ; call WSAStartup 
test eax, eax      ; eax = result. Is it zero? 
je SHORT [email protected]    ; yes, success. Go do stuff. 
            ; no, error code starts here 
+0

[WSAStartup] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms742213.aspx): * «В случае успеха функция ** WSAStartup ** возвращает ноль». * – IInspectable

+0

@IInspectable Благодаря! исправление ... –

1
MAKEWORD(a,b) is a macro that combine two BYTES (LOBYTE & HIBYTE) to make a word as the name says 

the result you have in: push 514   ; 00000202H 
is a (DWORD)(WORD) 0x0202 

00 00 02 02 
     HB LB 
[WORD] [WORD] 
[ DWORD ] 
. 
+0

[Справка по редактированию Markdown] (http://stackoverflow.com/editing-help). – IInspectable