2008-09-24 40 views
6

Tôi quyết định tự dạy ngôn ngữ lắp ráp.Tại sao tôi không thể thay đổi giá trị của thanh ghi phân đoạn? (MASM)

Tôi đã nhận ra rằng chương trình của tôi sẽ không biên dịch nếu tôi cố gắng thay đổi giá trị của bất kỳ thanh ghi phân khúc nào.

Mọi bài viết tôi đã tìm thấy đều nói rằng tôi thực sự có thể thay đổi giá trị của ít nhất 4 thanh ghi phân đoạn, vì vậy những gì cho?

Tôi thực sự chỉ quan tâm đến lý do tại sao tại thời điểm này, tôi không có bất kỳ mục đích thực sự nào trong việc thay đổi các địa chỉ này.

+2

Lỗi là gì? – Blorgbeard

+0

Theo một hệ điều hành, hoặc tự do? 16 chế độ bảo vệ thực hoặc 32 bit? Mã nào không biên dịch? Ví dụ tối thiểu 16 bit với các hiệu ứng quan sát được: https://github.com/cirosantilli/x86-bare-metal-examples/blob/d4aae6183b98564819107b44a77641979c35d2c3/segment_registers.S –

Trả lời

8

Bạn nói bạn đã quan tâm đến lý do tại sao, vì vậy:

Trong chế độ thực, một bộ phận là một "cửa sổ" 64K vào bộ nhớ vật lý và các cửa sổ này cách nhau 16 byte. Trong chế độ được bảo vệ, phân đoạn là cửa sổ cho bộ nhớ vật lý hoặc ảo, có kích thước và vị trí được xác định bởi hệ điều hành và có nhiều thuộc tính khác, bao gồm cấp độ đặc quyền mà quy trình phải truy cập.

Từ đây, mọi thứ tôi nói đều đề cập đến chế độ được bảo vệ.

Có một bảng trong bộ nhớ được gọi là bảng mô tả toàn cầu (GDT), là nơi thông tin về các kích thước cửa sổ và vị trí và các thuộc tính khác được lưu giữ. Cũng có thể có các bảng mô tả địa phương trên cơ sở từng quá trình và chúng hoạt động theo cách tương tự, vì vậy tôi sẽ chỉ tập trung vào GDT.

Giá trị bạn tải vào thanh ghi phân đoạn được gọi là bộ chọn phân đoạn phân đoạn. Nó là một chỉ mục trong GDT hoặc LDT, với một chút thông tin bảo mật bổ sung. Đương nhiên nếu một chương trình cố tải một bộ mô tả nằm ngoài giới hạn của GDT, một ngoại lệ sẽ xảy ra. Ngoài ra nếu quá trình này không có đủ đặc quyền để truy cập phân đoạn hoặc một thứ khác không hợp lệ, ngoại lệ sẽ xảy ra.

Khi ngoại lệ xảy ra, hạt nhân sẽ xử lý nó. Loại ngoại lệ này có thể sẽ được phân loại là lỗi phân đoạn. Vì vậy, hệ điều hành giết chết chương trình của bạn.

Có một cảnh báo cuối cùng: trong tập lệnh x86, bạn không thể tải giá trị ngay lập tức vào thanh ghi phân khúc. Bạn phải sử dụng thanh ghi trung gian hoặc toán hạng bộ nhớ hoặc POP vào thanh ghi phân khúc.

 
MOV DS, 160 ;INVALID - won't assemble 

MOV AX, 160 ;VALID - assembles, but will probably result in an 
MOV DS, AX ;exception, and thus the death of your program 

Tôi nghĩ cần phải chỉ ra rằng kiến ​​trúc cho phép đống phân đoạn. Nhưng AFAIK, khi nói đến các hệ điều hành chủ đạo x86, thanh ghi segment phục vụ chỉ có một vài mục đích:

  • Cơ chế bảo mật, chẳng hạn như giữ các quy trình không gian người dùng từ làm hại lẫn nhau hoặc hệ điều hành
  • Đối phó với nhiều/bộ vi xử lý đa lõi
  • Bộ nhớ cục bộ: tối ưu hóa, một số hệ điều hành (bao gồm Linux và Windows) sử dụng thanh ghi phân đoạn cho lưu trữ cục bộ (TLS). Vì các chủ đề chia sẻ cùng một không gian địa chỉ, nên khó có thể biết một chuỗi nào là "biết" nơi mà vùng TLS của nó không sử dụng cuộc gọi hệ thống hoặc lãng phí một thanh ghi ... nhưng vì các thanh ghi phân đoạn thực sự vô dụng, không có hại trong "lãng phí" chúng vì lợi ích của TLS nhanh. Lưu ý rằng khi thiết lập điều này, một hệ điều hành có thể bỏ qua thanh ghi phân đoạn và ghi trực tiếp vào sổ đăng ký bộ mô tả, là các thanh ghi "ẩn" được sử dụng để lưu trữ tra cứu GDT/LDT được kích hoạt bởi tham chiếu đến thanh ghi phân đoạn, trong trường hợp này nếu bạn thử để đọc từ phân khúc đăng ký, bạn sẽ không nhìn thấy nó.

Ngoài phân đoạn trên mỗi luồng cho TLS, thực sự chỉ có một số phân đoạn (số lần bộ xử lý) được sử dụng và chỉ bởi hệ điều hành. Các chương trình ứng dụng có thể hoàn toàn bỏ qua thanh ghi phân đoạn.

Điều này là do thiết kế hệ điều hành, không phải bất kỳ giới hạn kỹ thuật nào. Có thể có các hệ điều hành nhúng yêu cầu các chương trình không gian người dùng để làm việc với các thanh ghi phân đoạn, mặc dù tôi không biết bất kỳ điều gì.

+1

Bạn có chắc là bạn không thể tải thanh ghi phân khúc có giá trị ngay lập tức trên x86 không? Tôi đang xem Hướng dẫn dành cho nhà phát triển phần mềm kiến ​​trúc Intel (325462, Khối lượng kết hợp) và trên trang 1002 nó nói về lệnh MOV có mã opcode là 0x8E, dường như chuyển 'r/m16' sang thanh ghi phân đoạn. – amn

2

Bạn có đang viết các tệp thi hành Windows không?

Trong chế độ được bảo vệ (Win32), thanh ghi phân đoạn không được sử dụng nữa.

Reference:

mô hình bộ nhớ cũng là đáng kể khác nhau từ những ngày xa xưa của 16-bit thế giới . Theo Win32, chúng tôi không cần liên quan đến mô hình bộ nhớ hoặc phân đoạn nữa! Chỉ có một mô hình bộ nhớ : Mô hình bộ nhớ phẳng. Không còn phân đoạn 64K nào nữa. Bộ nhớ là không gian liên tục lớn gồm 4 GB. Điều đó cũng có nghĩa là bạn không có để phát với thanh ghi phân đoạn. Bạn có thể sử dụng bất kỳ đăng ký phân đoạn nào để giải quyết bất kỳ điểm nào trong không gian bộ nhớ. Đó là một trợ giúp tuyệt vời cho các lập trình viên. Đây là những gì làm cho Win32 lắp ráp lập trình dễ dàng như C.

+3

Đó là đồng bằng * sai *. Một số thanh ghi phân đoạn được sử dụng để lưu trữ cục bộ luồng và xử lý ngoại lệ. –

+0

Tôi (rõ ràng?) Có nghĩa là, "được sử dụng cho mục đích ban đầu của họ, bởi các chương trình không gian người dùng". OP đã đề cập đến tài liệu lỗi thời. – Blorgbeard

Các vấn đề liên quan