Так что кажется, что это очень простая проблема для всех, кто вообще знает о сборке, но я надеялся, что кто-нибудь сможет объяснить мне, в чем разница между следующими двумя частями кода, учитывая, что один из них приводит к ошибке сегментации идругой нет, но (мне) они кажутся логически эквивалентными.
Работает нормально:
char *src1; int esi_out, eax;
__asm__
__volatile__(
"lodsb\n\t;"
: "=&S" (esi_out), "=&a" (eax)
: "0" (src1)
);
printf("src1 %c @ %p, esi_out: %x, eax: %x\n", *src1, src1, esi_out, eax);
и печатает:
src1 w @ 0x7fffce186959, esi_out: ce18695a, eax: ce186977
Итак, я понимаю, что этот код должен загрузить значение src1 (которое является адресом) в ESI, скопировать это значение в EAX, увеличить адрес в ESI на 1 байт, а затем при выходе вывести эти значения в локальные переменные C esi_outи eax.src1 и esi_out выглядят корректно, но eax кажется выключенным.Что здесь происходит?
Второй бит кода - это то место, где мы видим сегмент, с которым я не могу разобраться:
__asm__
__volatile__(
"movl %%ebx, %%esi\n\t;"
//"lodsb\n\t;"
: "=&S" (esi_out), "=&b" (ebx), "=&a" (eax)
: "1" (src1)
);
printf("src1 %c @ %p, esi_out: %x, eax: %x, ebx: %x\n",
*src1, src1, esi_out, eax, ebx);
С закомментированной командой lodsb онавыдает:
src1 w @ 0x7ffff093b959, esi_out: f093b959, eax: f093b959, ebx: f093b959
И если команда lodsb не закомментирована, она вызывает ошибки.На мой взгляд, загрузка значения ESI напрямую, как в первом случае выше, загрузка его в EBX и затем перемещение его в ESI должна быть эквивалентной, нет?
Чего мне не хватает?Почему значение, записанное в EAX, не совпадает?Я написал эквивалентную программу непосредственно в ассемблер и прошел через нее, используя gdb, и она отлично работает.
Любое понимание будет с благодарностью.