AMD cần một số phòng để thêm mã opcode mới cho tiền tố REX
và một số hướng dẫn mới khác khi họ phát triển tiện ích mở rộng x86 64 bit. Họ đã thay đổi ý nghĩa của một số opcodes thành những hướng dẫn mới.
Một số hướng dẫn chỉ đơn giản là các dạng ngắn của các hướng dẫn hiện có hoặc nếu không thì không cần thiết. PUSHA
là một trong những nạn nhân. Nó không rõ ràng tại sao họ cấm PUSHA
mặc dù, nó dường như không chồng chéo bất kỳ opcodes hướng dẫn mới. Có lẽ chúng được dành riêng cho các mã opcode PUSHA
và POPA
để sử dụng trong tương lai, vì chúng hoàn toàn thừa và sẽ không nhanh hơn và sẽ không xuất hiện đủ thường xuyên trong mã thành vấn đề.
Trình tự PUSHA
là thứ tự của bảng mã lệnh: eax
, ecx
, edx
, ebx
, esp
, ebp
, esi
, edi
. Lưu ý rằng nó đã đẩy lùi esp
! Bạn cần biết esp
để tìm dữ liệu được đẩy!
Nếu bạn đang chuyển đổi mã từ 64 bit, mã PUSHA
không tốt, bạn cần cập nhật mã để đẩy thanh ghi mới r8
qua r15
.Bạn cũng cần lưu và khôi phục trạng thái SSE lớn hơn nhiều, xmm8
qua số xmm15
. Giả sử bạn đang đi để clobber chúng.
Nếu mã trình xử lý ngắt chỉ đơn giản là một nhánh để chuyển tiếp tới mã C, bạn không cần phải lưu tất cả các thanh ghi. Bạn có thể giả định rằng trình biên dịch C sẽ tạo mã sẽ được giữ nguyên rbx
, rbp
, rsi
, rdi
và r12
qua r15
. Bạn chỉ cần lưu và khôi phục rax
, rcx
, rdx
và r8
qua r11
. (Lưu ý: trên Linux hoặc các nền tảng System V ABI khác, trình biên dịch sẽ được bảo quản rbx
, rbp
, r12
- r15
, bạn có thể mong đợi rsi
và rdi
clobbered).
Thanh ghi phân khúc không giữ giá trị ở chế độ dài (nếu chuỗi bị gián đoạn đang chạy ở chế độ tương thích 32 bit, bạn phải giữ lại thanh ghi phân đoạn, nhờ ughoavgfhw). Trên thực tế, họ đã loại bỏ hầu hết phân đoạn ở chế độ dài, nhưng FS
vẫn được dành riêng cho hệ điều hành để sử dụng làm địa chỉ cơ sở cho dữ liệu cục bộ của luồng. Giá trị đăng ký tự nó không quan trọng, cơ sở của FS
và GS
được thiết lập thông qua MSRs 0xC0000100
và 0xC0000101
. Giả sử bạn sẽ không sử dụng FS
bạn không cần phải lo lắng về nó, chỉ cần nhớ rằng bất kỳ luồng dữ liệu cục bộ nào được truy cập bởi mã C có thể sử dụng bất kỳ TLS của luồng ngẫu nhiên nào. Hãy cẩn thận vì thư viện thời gian chạy C sử dụng TLS cho một số chức năng (ví dụ: strtok thường sử dụng TLS).
Tải giá trị vào FS
hoặc GS
(ngay cả trong chế độ người dùng) sẽ ghi đè FSBASE
hoặc GSBASE
MSR. Vì một số hệ điều hành sử dụng GS
là bộ nhớ "bộ xử lý cục bộ" (chúng cần một cách để có con trỏ đến cấu trúc cho mỗi CPU), chúng cần giữ nó ở một nơi không bị che khuất bằng cách tải GS
ở chế độ người dùng. Để giải quyết vấn đề này, có hai MSR được dành riêng cho thanh ghi GSBASE
: một hoạt động một và một bị ẩn. Ở chế độ hạt nhân, số GSBASE
của hạt nhân được giữ trong MSR GSBASE
thông thường và cơ sở chế độ người dùng nằm trong chế độ khác (ẩn) GSBASE
MSR. Khi bối cảnh chuyển từ chế độ hạt nhân sang ngữ cảnh chế độ người dùng và khi lưu ngữ cảnh chế độ người dùng và nhập chế độ hạt nhân, mã chuyển đổi ngữ cảnh phải thực hiện lệnh SWAPGS, hoán đổi giá trị của GSBASE
MSR hiển thị và ẩn. Vì hạt nhân của GSBASE
được ẩn an toàn trong MSR khác trong chế độ người dùng, mã chế độ người dùng không thể che dấu của hạt nhân GSBASE
bằng cách tải giá trị vào GS
. Khi CPU reenters chế độ hạt nhân, bối cảnh lưu mã sẽ thực hiện SWAPGS
và khôi phục của hạt nhân GSBASE
.
Tôi đọc trên [bài viết wiki] (http://en.wikipedia.org/wiki/X86-64) rằng x86-64 tương thích ngược với x86. Sẽ không loại bỏ một break break mà tương thích? –