แอสเซมบลีแบบอินไลน์ของ GNU เพื่อย้ายข้อมูล

ฉันต้องการเขียนจำนวนเต็ม 64 บิตไปยังตำแหน่งหน่วยความจำเฉพาะ

โค้ดตัวอย่าง C++ จะมีลักษณะดังนี้:

extern char* base;
extern uint64_t data;
((uint64_t *)base)[1] = data;

ต่อไปนี้เป็นความพยายามของฉันที่จะเขียนข้อความด้านบนแบบอินไลน์แอสเซมบลี:

uint64_t addr = (uint64_t)base + 8; 
asm volatile (
    "movq %0, (%1)\n\t"
    :: "r" (data), "r"(addr) : "memory"
    );

ข้อมูลข้างต้นใช้ได้กับโปรแกรมทดสอบขนาดเล็ก แต่ในแอปพลิเคชันของฉัน ฉันสงสัยว่ามีบางอย่างผิดปกติ

ฉันจำเป็นต้องระบุตัวถูกดำเนินการเอาต์พุตหรือข้อจำกัดอื่นใดข้างต้นหรือไม่

ขอบคุณ!


person MK.    schedule 18.03.2014    source แหล่งที่มา


คำตอบ (1)


เพียงแค่พูดว่า:

asm("mov %1, %0\n\t" : "=m"(*(uint64_t*)(base + 8)) : "r"(data) : "memory");

สิ่งที่ยุ่งยากคือเมื่อใช้ข้อจำกัด "m" คุณ (อาจขัดกับสัญชาตญาณ) ไม่ ให้ที่อยู่ แต่ให้สิ่งที่ใน C ดูเหมือน "ค่า" ของตัวแปรที่คุณต้องการเปลี่ยนแปลงแทน< br> นั่นเป็นสาเหตุว่าทำไม ในกรณีนี้ จึงมี pointer-cast-dereference แปลกๆ คอมไพเลอร์สำหรับสิ่งนี้ต้องแน่ใจว่าได้ใส่ที่อยู่ของตัวถูกดำเนินการเข้าไป

person FrankH.    schedule 19.03.2014
comment
เย็น! นั่นได้ผล ฉันยังลองใช้โค้ดดั้งเดิมของฉันโดยไม่สร้างตัวแปร addr เหมือนอย่างที่ฉันเคยเป็นและมันก็ใช้ได้ผลเช่นกัน ดังนั้นปัญหาดูเหมือนจะเกิดจากการเพิ่มประสิทธิภาพบางอย่างที่เกี่ยวข้องกับตัวแปร addr ระดับกลาง - person MK.; 20.03.2014