Dönüşümden sonraki kod, belirli bir eylemi yürütmez [yineleme]
AT&T sözdizimine dayalı olarak belirli bir kodu C ++ 'dan ASM'ye dönüştürmek için bir görev verildi, bu yüzden basit örneklerle başladım ve ilk sorunla karşılaştım.
egzersize başladığım kod
void func() {
int num = 1;
std::cout << "before: " << num << std::endl;
num = num << 3;
std::cout << "after: " << num << std::endl;
}
sonuç verir:
before: 1
after: 8
çeviri değişkenim num ilk yerel değişkendir, bu nedenle -4 (% ebp) adresinde olmalıdır
void func() {
int num = 1;
std::cout << "before: " << num << std::endl;
asm (
"mov -4(%ebp), %eax \n"
"sall $3, %eax \n"
"mov %eax, -4(%ebp) \n"
);
std::cout << "after: " << num << std::endl;
}
sonuç verir:
before: 1
after: 1
neden bu kodun num var üzerinde etkisi yoktur?
Yanıtlar
Yazdığınız kod uygulamaya özeldir. Sizin durumunuzda, kod büyük olasılıkla çalışmaz çünkü ebp
32 bitlik bir adresleme yazmacı kullanıyorsunuz, 64 bitlik bir makinede çalışırken, kullanan rbp
.
ANCAK buna yanlış yaklaşıyorsunuz. Ya saf derleme yazarsınız ya da yerel değişkenlerle doğru şekilde arabirim oluşturan doğru (genişletilmiş) C satır içi derlemesini kullanırsınız. Aksi takdirde, kendinizi deneyimlediğiniz gibi, bir şeyi değiştirir değiştirmez kod kırılacaktır.
bu yanıta göre satır içi asm şöyle görünmelidir:
asm ( "assembly code"
: output operands /* optional */
: input operands /* optional */
: list of clobbered registers /* optional */
);
böylece kodunuz şöyle görünebilir
asm (
"mov %0, %%eax;"
"sal $3, %%eax;"
"mov %%eax, %1;"
:"=r" (num)
:"r" (num)
:"%eax"
);
Ancak, belirtmeniz ve kullanmanız gerekmez eax
, bu nedenle kod basitleştirilebilir (ve açıklığa kavuşturulabilir)
asm (
"sal $3, %[num];"
:[num] "+r" (num)
);