Saat saya meneruskan pointer ke array dari Rust ke x86-64 Asm, register yang relevan (rdi, rsi) tampak meleset satu, menunjuk ke elemen 1 array, bukan elemen 0. Saya dapat mengurangi register untuk mengakses yang diinginkan lokasinya, tetapi saya khawatir dengan perilaku yang tidak terduga. Apakah ada penjelasan yang mungkin untuk hal ini yang saya abaikan?
Bagian paling relevan dari program sederhana untuk menggambarkan hal ini adalah sebagai berikut.
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
untuk konstanta 1-byte?mov byte ptr [rsi], 0xff
/mov byte ptr [rdi], 0xee
/xor eax,eax
jauh lebih pendek dan efisien. Sebagai bonus, itu akan benar-benar dirakit, tidak sepertimov byte [rdi], rax
yang memiliki ketidakcocokan antara ukuran operan byte dan qword. (al
adalah byte rendah RAX). Selain itu,.intel_syntax
GAS mirip MASM, jadi Anda memerlukanbyte ptr
, bukanbyte
bergaya NASM. Kecuali Rust menggunakan assembler lain yang hanya terlihat seperti GAS, ini bukan kode asm Anda yang sebenarnya. - person Peter Cordes   schedule 16.12.2018