I understand that the ret
imm16
(C2 imm16
) instruction with an operand of zero is no different than the operandless ret
(C3
) in its effect. However, when I explicitly give my assembler ret 0
, should it not encode that as the ret imm16
instruction since I explicitly provided the operand?
If I assemble the following code with the version of ml.exe that ships with VS2019 with the command ml file.asm /link /SUBSYSTEM:CONSOLE /ENTRY:stdMain
.386
.MODEL FLAT, STDCALL
.CODE
stdMain PROC
xor eax, eax
ret 0
stdMain ENDP
END
Then open the executable with a disassembler, I see the instruction that was encoded for ret
was C3
:
00401000: 33 C0 xor eax,eax
00401002: C3 ret
I can manually enforce the C2
instruction by hard coding the bytes for it:
.386
.MODEL FLAT, STDCALL
.CODE
stdMain PROC
xor eax, eax
db 0c2h, 0, 0 ; ret imm16=0
stdMain ENDP
END
Now I see the C2
instruction in the disassembled output:
00401000: 33 C0 xor eax,eax
00401002: C2 00 00 ret 0
Is it correct for an assembler to 'optimize' like that?