Самый простой способ ответить на этот вопрос - это скомпилировать его с помощью опции командной строки -S
, которая выводит вашу программу на C как код сборки.
Это то, что ваша функция main()
компилируется без какой-либо оптимизации (т. Е. С помощью переключателя командной строки -O0
). Я удалил некоторые избыточные заявления маркерных и добавил несколько замечаний:
main:
leal 4(%esp), %ecx # Create local storage on stack
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
subl $20, %esp
movl $12345, -12(%ebp) # Initialize `a` to 12345
cmpl $12346, -12(%ebp) # Compare with 12346
jne .L4
subl $12, %esp # If equal, ...
pushl $.LC0
call puts # print "YES"
addl $16, %esp
.L4:
nop
nop
movl -4(%ebp), %ecx # Tidy up and exit
leave
leal -4(%ecx), %esp
ret
Вы можете увидеть, что номера 12345 и 12346 включены в коде в инструкции movl
и cmpl
.
С оптимизацией код становится намного проще. Компилятор может видеть, что оператор if
никогда не оценивает значение true. Он также может видеть, что переменная a
никогда не используется. Это то, что main()
выглядит при компиляции с жесткой оптимизацией (-O3
):
main:
rep ret
(Примечание: Я составил это на 32-битной Ubuntu дружественного, но точно такая же оптимизация будет происходить на 64-битную машине .)
Почему маленький-vs-big не имеет значения? – Thilo
Я бы ожидал, что компилятор сможет оптимизировать сравнение. Вы уверены, что '0x303a', которое вы находите, является фактическим числом из исходного файла, а не какой-либо другой последовательностью из двух байтов, которая, случается, будет одинаковой? –
Если я сделаю то, что вы описали и скомпилируете с помощью 'gcc main.c', я вижу' 39 30' в смещении 00000538, всего несколько байт до '3A 30'. Если я использую 'gcc -O2 main.c' (например, включите оптимизацию), я не вижу ни одного из них (неудивительно, поскольку все это заканчивается« возвратом »). –