I don't know if it is asked but, I couldn't find it anything despite this question. Is it because of disassembler's fault? Or if it is right, why compiler generates this code?
; int __cdecl main(int argc, const char **argv, const char **envp)
main proc near ; CODE XREF: start-7Bp
var_4 = dword ptr -4
argc = dword ptr 8
argv = dword ptr 0Ch
envp = dword ptr 10h
push ebp
mov ebp, esp
push ecx
call ds:GetCurrentProcessId
mov [ebp+var_4], eax ; <---
mov eax, [ebp+var_4] ; <---
push eax
push offset output
call printf
add esp, 8
debugger_wait: ; CODE XREF: main+28j
call ds:IsDebuggerPresent
test eax, eax
jnz short debugger_present
jmp short debugger_wait
; ---------------------------------------------------------------------------
debugger_present: ; CODE XREF: main+26j
int 3 ; Trap to Debugger
xor eax, eax
mov esp, ebp
pop ebp
retn
main endp
Marked lines with arrows (from IDA output) shows two MOV operations which semantically equals to nothing (or is it?). This is my source code:
#include <stdio.h>
#include <Windows.h>
int main(int argc, char *argv[], char *envp[])
{
DWORD pid = GetCurrentProcessId();
printf("%d\n", pid);
while (!IsDebuggerPresent());
__asm int 0x3;
return 0;
}
Compiled with MSVC++ (19.00.24225.1):
cl.exe dnmProg.c
UPDATE: I tried other options, and both /O1 and /O2 doesn't have such structure, but /Ot has same instruction pair. When I compiled it with /Os there is:
call ds:GetCurrentProcessId
mov [ebp+var_4], eax ; <---
push [ebp+var_4] ; <---
push offset printf_parameter
call printf_
Thanks.