Trong assembly mình vẫn có thể dùng thanh gia 32bit (%eax) để lưu số kiểu nguyên long (64bit) không?
Trong assembly mình vẫn có thể dùng thanh ghi 32bit (%eax) để lưu số kiểu nguyên long (64bit) không?
Can 3 lít có đựng được 6 lít không anh em.
vậy tài liệu của thầy mình gi nhầm rồi sao ý ?
dòng đỏ
.data
ui DW 0xFFAABBCC
ul DQ ?
msg DB "ulong value is %lu", 0
; l = (unsigned long) ui;
mov eax, [ui]
mov esi, eax
mov [l], rsi ;nguyên văn
mov rdi, msg
call printf
Câu trả lời là KHÔNG, và bạn đang hiểu lầm code của thầy bạn mov %eax, %esi
=> This copies the value in %eax into %esi.
không phải đâu, dòng đỏ là thầy convert từ integer sang long mà
2 thằng đó đều 32 bit mà nhỉ
long là 64 bit mà a.
Nãy mình search thấy eax với esi đều là 32 bit
Cái này cũng vô chừng bên VS phải là long long
mới 64bit
Trở lại thì câu quan trọng nhất là mov %rsi, l
(qua %eax
thì hơi thừa). Sau đó ABI của printf là: rdi
trỏ vào chuỗi định dạng, rsi
là tham số (nguyên) thứ nhất.
Trong con cpu intel, họ cắt các thanh ghi ra làm các đơn vị nhỏ hơn, ví dụ như rax, đi xuống là eax (lower bits của rax), xuống nữa là ax (lower bits của eax), xuống nữa là al (lower bits của ax) và ah (higher bits của ax). Code chả có gì không hợp lệ, vấn đề gì nằm ở ý nghĩa thì mình không biết.
Compiler của bạn có cho ra mã máy cuối cùng không, nhìn cái là hiểu ngay, còn chưa biết ul của bạn nó là gì đây?
Cả long và int là như nhau, 32 bit. 64 bit là kiểu dữ liệu long long , hoặc là double , chú ý nhé bạn
Ngoài ra nếu muốn lưu dữ liệu 64bit vào thanh ghi 32 bit, bạn có thể cắt đôi kiểu 64 bit ra thành 2 temp data , mỗi cái 32 bit. Trong assembly thì chưa làm bao giờ nhưng trong C bạn có thể thử thế này
int result1 = ( int ) ( data64 & 0x0000FFFF ); // lưu 32 bit thấp
int result2 = ( int )( data64 >> 32 ); // lưu 32 bit cao
Còn nếu bạn gán trực tiếp thanh ghi , giả sử như câu lệnh bôi đỏ kia , thì vẫn chạy nhưng data sẽ bị mất 32 bit cao
Nitpick: Trên Unixes thì long = 64