Почему смещение компилятора осталось на 0?
После того, как я написал эту простую программу, когда я перешел в режим разборки в Visual Studio, я заметил что-то странное: компилятор добавил команду сдвинуть влево на 0 бит.
Почему он это делает?
Это код С++:
#include <iostream>
using namespace std;
int main(int argc, char **argv) {
if (argc != 3)
return 0;
if (strcmp(argv[1], "-r") == 0) {
printf("test");
}
return 0;
}
Это код сборки:
...
return 0;
00131C94 xor eax,eax
00131C96 jmp main+57h (0131CC7h)
if (strcmp(argv[1], "-r") == 0) {
00131C98 push offset string "-r" (0138B30h)
00131C9D mov eax,4
00131CA2 shl eax,0 <------------------------- HERE
00131CA5 mov ecx,dword ptr [argv]
00131CA8 mov edx,dword ptr [ecx+eax]
00131CAB push edx
00131CAC call _strcmp (01313D9h)
00131CB1 add esp,8
00131CB4 test eax,eax
00131CB6 jne main+55h (0131CC5h)
printf("test");
00131CB8 push offset string "test" (0138BD0h)
00131CBD call _printf (01313E8h)
00131CC2 add esp,4
...
Ответы
Ответ 1
Обратите внимание, что это используется при оценке argv[1]
.
В общем случае argv[N]
должен быть переведен компилятором на *((char**) ((char*) argv + N * sizeof *argv))
: каждый указатель sizeof *argv
bytes после следующего. Когда N
не известно во время компиляции, необходимо, чтобы оно было там, и shl
является обычным способом. *
Так как N
известно во время компиляции, но вы не включили оптимизацию, я бы предположил, что это скомпилировалось бы
00131C9D mov eax,1
00131CA2 shl eax,2
Очевидно, Visual Studio может упростить это, что вы видите, даже когда оптимизация отключена, но без оптимизаций она все еще не может полностью избавиться от shl
.
* В этом конкретном случае shl
не понадобится, даже если N
не известно во время компиляции: [ecx+eax*4]
можно получить с помощью одной команды, Это будет другая оптимизация, которая обычно выполняется.