Kode setelah konversi tidak menjalankan tindakan tertentu [duplikat]
Saya diberi tugas untuk mengubah kode tertentu dari C ++ ke ASM berdasarkan sintaks AT&T, jadi saya mulai dengan contoh sederhana dan mengalami masalah pertama.
kode tempat saya memulai latihan
void func() {
int num = 1;
std::cout << "before: " << num << std::endl;
num = num << 3;
std::cout << "after: " << num << std::endl;
}
yang memberikan hasil:
before: 1
after: 8
variabel terjemahan saya num adalah variabel lokal pertama jadi harus di alamat -4 (% ebp)
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;
}
yang memberikan hasil:
before: 1
after: 1
mengapa kode ini tidak berpengaruh pada num var?
Jawaban
Kode yang Anda tulis sangat spesifik untuk implementasi. Dalam kasus Anda, kode tersebut kemungkinan besar tidak berfungsi karena Anda menggunakan ebp
register pengalamatan 32-bit, saat Anda menjalankan mesin 64-bit, yang menggunakan rbp
.
NAMUN Anda salah mendekati ini. Entah Anda menulis perakitan murni, atau Anda menggunakan perakitan inline C yang benar (diperpanjang), yang dengan benar berinteraksi dengan variabel lokal. Jika tidak, kode akan rusak segera setelah Anda mengubah sesuatu, seperti yang Anda alami sendiri.
menurut jawaban ini asm sebaris akan terlihat seperti:
asm ( "assembly code"
: output operands /* optional */
: input operands /* optional */
: list of clobbered registers /* optional */
);
sehingga kode Anda akan terlihat seperti
asm (
"mov %0, %%eax;"
"sal $3, %%eax;"
"mov %%eax, %1;"
:"=r" (num)
:"r" (num)
:"%eax"
);
Namun, Anda tidak perlu menentukan dan menggunakan eax
, sehingga kode dapat disederhanakan (dan diklarifikasi) menjadi
asm (
"sal $3, %[num];"
:[num] "+r" (num)
);