2010-08-17 44 views
12

Tôi đang cố gắng học ngôn ngữ lắp ráp và tôi cần làm rõ về điều gì đó. Xin vui lòng sửa tôi nếu tôi sai về bất kỳ điều này kể từ khi tôi không biết nhiều về lắp ráp.Phân bổ bộ nhớ lắp ráp

Tất cả các hướng dẫn tôi xem đều có các biến của chương trình lắp ráp được gán cho địa chỉ bộ nhớ như 0x0000 và tôi có thể hiểu rằng bạn phải chỉ định địa chỉ bộ nhớ theo cách thủ công trong assembly, nhưng làm cách nào để biết địa chỉ nào cần sử dụng?

Rõ ràng việc bắt đầu ở địa chỉ bộ nhớ thấp nhất có thể có ý nghĩa, nhưng nếu biến bạn đang gán lớn hơn bộ nhớ có sẵn tại 0x0000 thì sao? Biến số được đề cập có chạy qua 0x0001 hoặc 0x0002 không? Nếu nó đã không sẽ làm lộn xộn lên các biến khác được gán không gian với số tương tự (hoặc là bạn không phải gán cho họ mà đóng)?

Nếu tôi có hai chương trình được viết trong assembly chạy cùng một lúc (trong hệ điều hành hiện đại) và tôi đã sử dụng cùng một địa chỉ bộ nhớ trong cả hai chương trình, sẽ có một chương trình xung đột với chương trình khác. có sẵn địa chỉ bộ nhớ bất kể những gì đã thực sự được viết trong chương trình?

Bất kỳ thông tin nào về chủ đề đều được đánh giá cao.

Trả lời

18

Câu trả lời cho câu hỏi thứ hai của bạn (trên hầu hết các hệ điều hành hiện đại) là bộ nhớ ảo.

Bạn bắt đầu ở lớp phần cứng với bộ nhớ vật lý. Đó là những thứ bạn thực sự có thể chọc bằng ngón tay của bạn. Đây là những gì hệ điều hành nhìn thấy. Hệ điều hành cho phép bạn chạy các tiến trình trên một trừu tượng được gọi là bộ nhớ ảo.

Mỗi quá trình sẽ có không gian bộ nhớ ảo riêng. Vì vậy, nó có thể giả vờ rằng đó là quá trình duy nhất chạy, và nó có tấn bộ nhớ. Sau đó, mỗi khi bạn truy cập bộ nhớ, bạn cung cấp một địa chỉ ảo, được ánh xạ tới một địa chỉ vật lý. Hệ điều hành giữ một bảng trong đó địa chỉ ảo được ánh xạ tới địa chỉ vật lý thực tế nào trong RAM. Thông thường, điều này cũng được thực hiện với một số phần cứng đặc biệt (đơn vị quản lý bộ nhớ MMU) vì lý do hiệu suất, nhưng bạn cũng có thể thực hiện nó 100% trong phần mềm.

Vì vậy, khi bạn nói 0x000 trong chương trình của mình, đó là địa chỉ ảo. Nó được dịch sang một địa chỉ vật lý của máy tính khi bạn đọc hoặc viết. Vì vậy, trong một quá trình khác, cùng một địa chỉ ảo 0x000 ánh xạ tới một địa chỉ vật lý khác. Hệ thống này cho phép bạn viết chương trình của bạn mà không biết chính xác có bao nhiêu RAM, hoặc địa chỉ chương trình của bạn sẽ được nạp vào. Nó cũng ngăn chương trình của bạn khỏi bộ nhớ gián đoạn thuộc về một chương trình khác.

Đối với phần đầu tiên, tuyệt đối. Các loại dữ liệu khác nhau có lượng bộ nhớ khác nhau. Bạn phải biết bao nhiêu không gian bạn cần khi bạn đặt ra các cấu trúc dữ liệu của bạn. Ngoài ra còn có các vấn đề liên kết byte để ghi nhớ. Các kiểu dữ liệu nhiều byte (ví dụ các số dấu phẩy động) thường phải bắt đầu tại một địa chỉ chia hết cho 2 hoặc 4 hoặc số byte cần để lưu trữ một float - đó là yêu cầu của bộ xử lý hoặc RAM.Vì vậy, bạn không thể chỉ co tất cả các dữ liệu của bạn với nhau, một byte sau khi tiếp theo, bạn phải đặt nó ra theo một thứ tự cụ thể như lắp ghép các mảnh ghép nếu bạn muốn giảm thiểu bộ nhớ không sử dụng.

+0

Cảm ơn câu trả lời chi tiết! Trong phần cuối của câu trả lời của bạn, làm thế nào để tính toán chính xác bao nhiêu không gian là cần thiết cho mỗi bit dữ liệu? tự tính toán hàng trăm biến cho một chương trình có vẻ không khả thi. Sử dụng từ ngữ của bạn, làm thế nào để bạn 'lay nó ra'? – ubiquibacon

+0

Tôi chưa bao giờ làm việc với assembly trong bất kỳ dự án lớn nào, nhưng heuristic đã được đề xuất trong lớp OS của tôi là sắp xếp các biến theo kích thước và sau đó đặt các biến nhỏ nhất ở các địa chỉ bộ nhớ thấp nhất. Đây không phải lúc nào cũng là bố cục tốt nhất - bạn có thể phù hợp với các loại dữ liệu nhỏ giữa các loại dữ liệu lớn. Bạn có thể biết được loại biến của bộ nhớ cần bao nhiêu bộ nhớ - hãy tham khảo tài liệu cho ngôn ngữ lắp ráp của bạn. Hãy nhớ rằng, một biến chiếm cùng một lượng bộ nhớ thông qua toàn bộ quá trình chạy chương trình của bạn. Nó không thể "phát triển" được. Đó là lý do tại sao sự tràn ngập xảy ra. –

+1

Câu trả lời hay, chỉ một lần sửa. Việc căn chỉnh dữ liệu đúng cách không phải là về tiết kiệm dung lượng, vì tất cả các bộ nhớ liền kề của nó đều là. Nó đã làm với cách dữ liệu xe buýt ánh xạ vào bộ nhớ. 8 bit đầu tiên bắt đầu tại địa chỉ 0, 8 bit tiếp theo kết nối đến địa chỉ 1. Điều này có nghĩa là một số nguyên 16 bit bắt đầu tại địa chỉ 0 có thể được đọc trong một lần đọc bởi vì nó sử dụng cả hai mặt của bus dữ liệu. Tuy nhiên, nếu một số nguyên 16 bit bắt đầu từ 1, bây giờ nó phải thực hiện hai lần đọc để có được toàn bộ số nguyên. Đối với các số nguyên 32 bit, chúng nên bắt đầu trên các địa chỉ chia hết cho 4 vì cùng một lý do. – Despertar

1

Phụ thuộc vào mục tiêu và loại bộ nhớ (RAM, ROM, v.v.) mà bạn đang nói đến. Nếu bạn đang nói về RAM một dự án nhúng nhỏ, bạn có thể chỉ có một vài tệp để theo dõi và các trang dữ liệu cho vi sẽ cho bạn biết địa chỉ vùng nhớ khác nhau. Trong trường hợp có một số 'mô-đun', bạn sẽ sử dụng trình liên kết để liên kết các tệp đối tượng vào tệp thực thi. Trình liên kết có thể gán lại địa chỉ bộ nhớ để chúng không trùng lặp hoặc bạn có thể có tệp trung tâm nơi tất cả các vị trí bộ nhớ được xác định và các mô-đun khác sử dụng tài nguyên này làm tài nguyên. Lấy làm tiếc. Đó là một câu hỏi lớn với rất nhiều câu trả lời.

5

Đây không phải là câu trả lời chính xác nhưng trong cuốn sách này có câu trả lời. Tôi chỉ có thể giới thiệu nó. Nó sẽ dạy cho bạn những điều cơ bản, giống như tên cho biết đó là lập trình từ mặt đất lên.

ProgrammingGroundUp

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