2011-09-23 15 views
5

Tôi đã đọc rằng nếu bit eflags 18 (kiểm tra liên kết AC) có thể được sửa đổi, bạn biết CPU là 486 hoặc mới hơn. Trên 386, bit chống sửa đổi.Làm thế nào để x86 eflags bit 18 (kiểm tra căn chỉnh) hoạt động? (Liên quan đến kiểm tra 386 so với 486 và sau đó.)

tôi đã dỡ bỏ các mã lắp ráp sau từ this site và bổ sung ý kiến ​​đầy đủ (để lại cú pháp lẻ còn nguyên vẹn):

asm 
    mov bx,sx   ; Save the stack pointer to bx (is sx a typo or a real register?). 
    and sp,$fffc   ; Truncate the stack pointer to a 4-byte boundary. 
    pushfl    ; Push the eflags register to the stack. 
    pop eax    ; Pop it into eax. 
    mov ecx,eax   ; Save the original eflags value into ecx. 
    xor eax,$40000  ; Flip bit 18 in eax. 
    push eax    ; Push eax to the stack. 
    popfl     ; Pop modified value into eflags. 
    pushfl    ; Push eflags back onto the stack. 
    pop eax    ; Pop it into eax. 
    xor eax,ecx   ; Get changed bits from the original value. 
    setz al    ; Set al register to 1 if no bits changed (0 otherwise). 
    and sp,$fffc   ; Truncate the stack pointer to a 4-byte boundary. 
    push ecx    ; Push ecx (original eflags) to stack. 
    popfl     ; Pop it into eflags to restore the original value. 
    mov sp,bx   ; Restore the original stack pointer. 
end ['eax','ebx','ecx']; 

CPU là 386 nếu đăng ký al được thiết lập để 1 lúc kết thúc (giả định từ đầu rằng nó không phải là cũ hơn), và nó là một 486 hoặc mới hơn nếu không. Tôi hiểu phần này.

Điều tôi không hiểu là tại sao con trỏ ngăn xếp phải được cắt ngắn thành ranh giới 4 byte trước khi thực hiện kiểm tra sửa đổi cờ? Tôi giả định rằng nó có nghĩa là để thiết lập bit 18, vì nó là bit liên kết sau khi tất cả ... nhưng xor với 0x40000 sẽ lật bit bất kể giá trị của nó. Nói cách khác, kiểm tra sửa đổi phải có kết quả tương tự bất kể giá trị ban đầu, phải không?

Nếu câu trả lời là không, tốt nhất của tôi [không được giáo dục] đoán là "tại sao" là "Có thể các hướng dẫn đẩy/bật sau đây có thể buộc căn chỉnh? Điều này sẽ căn chỉnh con trỏ ngăn xếp trước đó và khiến bit căn chỉnh lật từ 0 đến 1 của chính nó. Trong trường hợp đó, một sửa đổi thành công sẽ xuất hiện không thành công và ngược lại. " (EDIT: Điều này là chắc chắn không chính xác, bởi vì bit liên kết là về thực thi hơn là theo dõi liên kết. Plus, tôi nghi ngờ rằng pop/đẩy sẽ buộc liên kết trên một stack chưa xếp trước đó anyway.)

Ngay cả khi đó là trường hợp mặc dù, mục đích của việc sắp xếp các con trỏ ngăn xếp một lần nữa sau khi thử nghiệm (ngay trước khi khôi phục lại các eflags gốc và con trỏ ngăn xếp) là gì? Không phải là nó đã được trên một ranh giới 4-byte từ trước? Nếu không, làm thế nào có thể đã thay đổi từ đẩy/popping giá trị 4 byte?

Tóm lại, một số hướng dẫn có vẻ dư thừa đối với tôi và tôi cảm thấy rằng tôi phải thiếu điều gì đó quan trọng. Bất cứ ai ở đây có thể giải thích nó?

(Câu hỏi phụ: Dòng đầu tiên sao chép giá trị từ "sx" vào bx. Tôi chưa bao giờ thấy tham chiếu đến sổ đăng ký sx ở bất kỳ đâu. Nó thực sự tồn tại hay đó là lỗi đánh máy? 'X' key là khá xa phím 'p', ít nhất là trên bàn phím của Mỹ.)

EDIT: Bây giờ câu hỏi này đã được trả lời, tôi quyết định xóa nhận xét không đúng từ hai dòng căn chỉnh trong mã. Ban đầu tôi đã giả định rằng việc sắp xếp ngăn xếp sẽ thiết lập bit liên kết, và tôi đã viết nó vào nhận xét của tôi (phần còn lại của câu hỏi tiếp tục với logic không chính xác này). Thay vào đó, bit kiểm tra căn chỉnh thực sự là về việc thực thi căn chỉnh (thay vì theo dõi nó), như câu trả lời của flolo liên quan đến sigbus. Tôi đã quyết định sửa các nhận xét để tránh nhầm lẫn những người có câu hỏi tương tự.

+0

Bạn đã vào bảo tàng nào để tìm 386? Bạn nên đặt nó trở lại. –

+0

LOL! Tôi đã không bao giờ chạm vào một máy tính để bàn 386, kiến ​​thức của tôi ... Tôi đã sai lầm với 286 cũ trở lại trong ngày, nhưng tôi bỏ qua từ đó đến một Pentium 75. Tôi chỉ quyết định bao gồm căn cứ của tôi trước khi gọi hướng dẫn CPUID (trước tiên hãy chắc chắn rằng bạn không có 386, sau đó kiểm tra bit eflags 21 cho sự hiện diện của CPUID), trong cơ hội không vui, một số điên đã quyết định sử dụng mã của tôi trên phần cứng cổ. Tôi đoán tôi chỉ là hậu môn ... nhưng ít nhất tôi không kiểm tra CPU 8-bit và 16-bit, vì các trình biên dịch hiện đại dường như thậm chí không tạo mã cho những người đó. ;) –

Trả lời

4

Đoán của tôi rất dễ: Mã không muốn sigbus. Trong trường hợp liên kết kiểm tra chưa được đặt và bạn đã đặt nó, bạn thực sự bật kiểm tra căn chỉnh (khi cài đặt nó hoạt động). Và khi con trỏ ngăn xếp không liên kết với ranh giới 4 byte, hãy đoán xem điều gì sẽ xảy ra? Bạn có một truy cập bộ nhớ không được ký hiệu, kết quả là một sigbus. Và nếu bạn không muốn cho phép truy cập bộ nhớ không hợp lệ xảy ra (vì bạn chỉ muốn thay đổi bit cho mục đích thử nghiệm), bạn phải cẩn thận khi tất cả các truy cập trong khi bạn thử nghiệm giả định trường hợp xấu nhất (đó là: bạn đã kích hoạt nó) , và ngăn xếp của bạn là trước khi nó không liên kết, bởi vì nó không cần, đến nay các kiểm tra đã bị vô hiệu hóa).

+0

Cảm ơn bạn. Điều đó hoàn toàn giải thích hướng dẫn căn chỉnh đầu tiên; Tôi đã không nhận ra tầm quan trọng của bit được thiết lập (tiềm năng cho một sigbus). Bạn có biết tại sao liên kết được đặt lại sau, khi có vẻ rõ ràng rằng bộ nhớ đã được căn chỉnh chưa? –

+1

+1 Đây là lý do (Có vẻ như nó là từ một đoạn pascal và do đó sẽ được chạy ra khỏi một ngăn xếp 16-bit, mà không được đảm bảo để được 32-bit liên kết). Sự liên kết thứ hai của sp không thực sự trông thừa, nó có lẽ chỉ ở đó để nhấn mạnh rằng việc kiểm tra căn chỉnh có thể được kích hoạt lại bằng lệnh popfl. – user786653

+0

Cảm ơn một lần nữa, các bạn! Trừ khi và cho đến khi người khác đến và giải thích tại sao căn chỉnh thứ hai thực sự cần thiết, tôi sẽ đánh dấu điều này là được chấp nhận và cho rằng căn chỉnh thứ hai là thừa. –

2

Không có đăng ký SX. Hoặc là lỗi đánh máy hoặc đề cập đến một vị trí bộ nhớ.

+0

Cảm ơn. Tôi đã được ngân hàng trên đó khi tôi đã viết bình luận về tiết kiệm con trỏ ngăn xếp trong dòng đầu tiên, nhưng nó là tốt để có xác nhận rằng nó không phải là một số đăng ký phụ tối nghĩa. (Tôi đoán rằng sẽ không có ý nghĩa anyway: 16-bit sp được khôi phục từ bx 16-bit, do đó, không có gì ít hơn 16 bit sẽ làm gì để tiết kiệm giá trị ban đầu để bx ở nơi đầu tiên.) –