0

I have wrote a c program that uses the WINAPI library (specifically WSA - Sockets) and instead of compiling the source code asked the compiler to emit assembly source instead to study how it works on the lower level.

When coming across this line below I noticed in the assembly that there is no reference to the first argument of my WINAPI function.The function MAKEWORD in WSAStartup.

What is really happening here? There is no references in my assembly code to MAKEWORD but a hint of push 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 __imp__WSAStartup@8
     test    eax, eax
     je  SHORT $LN4@main

Note: The WSAStartup function initiates use of the Winsock DLL by a process.

I can provide more info if needed

MD XF
  • 7,860
  • 7
  • 40
  • 71
Jebathon
  • 4,310
  • 14
  • 57
  • 108
  • `MAKEWORD` is just a compiler macro (not a function) that packs bytes into a WORD - you should be able to find the definition in the compiler's header collection somewhere (it probably looks something like `#define MAKEWORD(x,y) (x<<8+y)`. Look at the bytes in the value getting pushed on the stack - 0x02, 0x02. – nobody Oct 19 '15 at 00:36
  • `lea` is `load effective address` which is loading the addressed computed from `DWORD PTR _wsa$[ebp]` into `eax`, `514` looks to be the syscall for `ioctl` (32-bit). Both `eax` and `514` are pushed to the stack and a then it looks like the call is made to execute your `ioctl` request, with the return in `eax` tested after the call. – David C. Rankin Oct 19 '15 at 00:46
  • 1
    @DavidC.Rankin: There is no `IOCTL` code. There's also no syscall. `514` is the first argument passed to [WSAStartup](https://msdn.microsoft.com/en-us/library/windows/desktop/ms742213.aspx) (pushed onto the stack right to left). The syscall happens when the code calls `DWORD PTR __imp__WSAStartup@8`. The `test eax, eax` is likely the assembly version of an `if` statement. – IInspectable Oct 19 '15 at 01:14
  • Thank your for clearing that up. The only reference I have for the 514 is `/usr/include/asm/unistd_32.h` Which states `#define __NR_ioctl (__X32_SYSCALL_BIT + 514)` which I apparently misread. – David C. Rankin Oct 19 '15 at 02:32
  • 1
    @DavidC.Rankin: 514 is `2 << 8 | 2`, the result of evaluating the preprocessor macro `MAKEWORD( 2, 2 )`. – IInspectable Oct 19 '15 at 10:20

3 Answers3

4

MAKEWORD is a function-like preprocessor macro, that is defined as

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

Since you are using it with compile-time constants (2 and 2), the compiler can compute the final value by shifting the second argument 8 bits to the left and adding the first: 2 << 8 + 2. The result is 512 + 2, the value 514 you are seeing pushed onto the stack.

IInspectable
  • 46,945
  • 8
  • 85
  • 181
  • So is there any semantic meaning to putting MAKEWORD(2,2) instead of 514? Or just some small optimization? – Jebathon Oct 22 '15 at 14:36
  • @BDillan: There is no optimization at all, it's pure semantics. Consider someone reading your code, what would convey more meaningful information: `514` or `MAKEWORD(2,2)`? The latter makes it a lot easier to see, that you want to initialize *Version 2.2*. The compiler doesn't care which one you use. The resulting opcodes will be the same. – IInspectable Oct 22 '15 at 15:07
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   ]
.
milevyo
  • 2,165
  • 1
  • 13
  • 18
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 __imp__WSAStartup@8 ; call WSAStartup
test eax, eax                      ; eax = result. Is it zero?
je   SHORT $LN4@main               ; yes, success. Go do stuff.
                                   ; no, error code starts here
Leandro Caniglia
  • 14,495
  • 4
  • 29
  • 51
  • [WSAStartup](https://msdn.microsoft.com/en-us/library/windows/desktop/ms742213.aspx): *"If successful, the **WSAStartup** function returns zero."* – IInspectable Oct 19 '15 at 01:29