เมื่อฉันส่งพอยน์เตอร์ไปยังอาร์เรย์จาก Rust ไปยัง x86-64 Asm รีจิสเตอร์ที่เกี่ยวข้อง (rdi, rsi) ดูเหมือนจะปิดไปทีละอัน โดยชี้ไปที่องค์ประกอบ 1 ของอาร์เรย์แทนที่จะเป็นองค์ประกอบ 0 ฉันสามารถลดค่ารีจิสเตอร์เพื่อเข้าถึงค่าที่ต้องการได้ สถานที่ แต่ฉันกังวลเกี่ยวกับพฤติกรรมที่ไม่คาดคิด มีคำอธิบายที่เป็นไปได้สำหรับสิ่งนี้ที่ฉันมองข้ามไปหรือไม่?
ส่วนที่เกี่ยวข้องมากที่สุดของโปรแกรมง่ายๆ เพื่ออธิบายสิ่งนี้มีดังนี้
main.rs
extern crate utilities;
fn main() {
let input: [u8;8] = [0;8];
let output: [u64; 1] = [0;1];
let input_ptr = input.as_ptr();
let output_ptr = output.as_ptr();
utilities::u8tou64(input_ptr,output_ptr);
for i in 0..8 {print!("{:02X}", input[i]);} // byte 1 will be 0xEE
println!();
println!("{:016X}", output[0].swap_bytes()); /* byte 1 position of the u64
will be 0xFF */
println!("{:02X}", unsafe{*input_ptr.offset(1)}); /* modifying byte at address
passed into rdi in Asm function modifies input_ptr.offset(1) when expected
behavior was modification of input_ptr with no offset, e.g. input[0] */
}
u8_to_u64.S
.globl u8_to_u64
.intel_syntax noprefix
u8_to_u64:
mov rax, 0xff
mov byte [rsi], rax
mov rax, 0xee
mov byte [rdi], rax
xor rax, rax
retq
mov r64, sign_extended_imm32
สำหรับค่าคงที่ 1 ไบต์mov byte ptr [rsi], 0xff
/mov byte ptr [rdi], 0xee
/xor eax,eax
สั้นกว่าและมีประสิทธิภาพมากกว่ามาก เป็นโบนัสพิเศษ มันจะประกอบกันจริง ๆ ซึ่งแตกต่างจากmov byte [rdi], rax
ซึ่งมีขนาดตัวถูกดำเนินการไบต์และ qword ไม่ตรงกัน (al
คือไบต์ต่ำของ RAX) นอกจากนี้.intel_syntax
ของ GAS ก็เหมือนกับ MASM ดังนั้นคุณจึงต้องใช้byte ptr
ไม่ใช่byte
แบบ NASM เว้นแต่ว่า Rust จะใช้แอสเซมเบลอร์อื่นที่ดูเหมือน GAS เท่านั้น นี่ไม่ใช่รหัส asm ที่แท้จริงของคุณ - person Peter Cordes   schedule 16.12.2018