2012-10-09 25 views
6

Tuyên bố từ chối trách nhiệm: Tôi mới sử dụng C/C++.Tôi có thể truy cập mọi thứ trong bộ nhớ không?

Nếu tôi đã manually assign a memory address thành biến trong C, sau đó thử lặp lại giá trị đó ... tôi có quyền truy cập không giới hạn để xem mọi thứ trong bộ nhớ hoặc có hạn chế không?

Ví dụ:

char * p = (char *)0x28ff44; 
printf("Memory value: %c", *p); 

tôi đoán rằng sẽ sụp đổ khủng khiếp nếu những gì là tại địa chỉ đó không phù hợp với kích thước của kiểu char, nhưng nó chỉ đơn thuần là một ví dụ. Những gì tôi thực sự tò mò về là nếu một cái gì đó như thế này là có thể hoặc làm hệ điều hành áp đặt hạn chế và chỉ cho phép bạn truy cập bộ nhớ trong không gian bộ nhớ nhất định của bạn?

+1

Bạn có thể tìm thấy một số thông tin thú vị tại một câu hỏi khác trên ngăn xếp tràn: http://superuser.com/questions/189876/how-os-detects-memory-access-violations – fycth

+0

Wow, cảm ơn tất cả các câu trả lời tuyệt vời. Tôi nhớ cố gắng học C trở lại trường trung học (khoảng 10 năm trước bây giờ tôi đoán) và tôi dường như nhớ lại rằng vào thời điểm tôi đang dabbling, thường có một không gian bộ nhớ và các vấn đề có thể xảy ra bên trong nó. Thật tốt khi thấy có nhiều sự bảo vệ tại chỗ hơn cho những noobs cấp thấp như bản thân tôi. –

+1

Lưu ý phụ, '% s' là chuỗi định dạng sai cho một ký tự đơn, bạn cần'% c';) – slugonamission

Trả lời

5

Ồ, tốt thôi.

Về mặt kỹ thuật, có, bạn có thể. Trong các thiết bị nhúng không sử dụng MMU hoặc bất kỳ hình thức bảo vệ nào (hoặc bạn biết, x86 ở chế độ thực), bạn có thể thực hiện chính xác những gì bạn đã đăng ở đó. Bạn cũng có thể làm điều đó trong chế độ người dùng trên bất kỳ hệ điều hành nào, nhưng cơ hội bạn thực sự nhấn vào bộ nhớ hợp lệ là rất nhỏ.

Trong thực tế, không, bạn không thể làm điều đó. Với bộ nhớ ảo và bảo vệ bộ nhớ, rất có khả năng vùng bạn cố truy cập sẽ không được ánh xạ và do đó, sẽ thất bại. Ngoài ra, nếu bạn nhấn vào bộ nhớ được bảo vệ (ví dụ: bất kỳ thứ gì thuộc hệ điều hành), quyền truy cập của bạn sẽ không thành công. Cả hai kịch bản này là nguyên nhân gây ra lỗi phân đoạn.

Tuyên bố của bạn hợp lệ (đối với các định nghĩa khác nhau hợp lệ) và chương trình sẽ cố gắng truy cập vào bộ nhớ bạn đã yêu cầu. Nó chỉ là nó có thể không thực sự được ánh xạ tới bất cứ điều gì.

Điều đáng lưu ý là đây là cách hoạt động của I/O được ánh xạ bộ nhớ. Nói rằng tôi có một thanh ghi điều khiển phần cứng khi được ghi vào, viết một byte trên dòng UART/nối tiếp (và, để đơn giản, nó hoạt động như ma thuật và không cần bất kỳ thanh ghi nào khác được thiết lập). Trong C, điều này sẽ được viết như sau cho thiết bị quá đơn giản của tôi:

#define UART1_OUT 0xFC56 

volatile char* uart = UART1_OUT; // Definition of pointer to variable. 
            // volatile is required here. Look it up, but 
            // it basically stops your compiler optimising 
            // anything to do with this variable 

*uart = 'A';      // Write an A character to the serial line 

Tất nhiên, các thiết bị thực tế phức tạp hơn một chút;).

+0

Tôi đoán bạn phải nhập truyền giá trị địa chỉ, trình biên dịch sẽ đưa ra lỗi. –

+0

Không, đó là một cảnh báo theo mặc định trong GCC. Tôi không chắc về Visual C và Clang. – slugonamission

2

Điều này phụ thuộc vào kiến ​​trúc máy tính và hệ điều hành mà chương trình của bạn chạy. Hệ điều hành hiện đại có khái niệm về bộ nhớ protectedvirtual. Với bộ nhớ ảo, các địa chỉ bộ nhớ không đề cập đến bộ nhớ vật lý, mà là không gian bộ nhớ ảo được gán cho ứng dụng hiện tại. Cố gắng đọc hoặc ghi vào bộ nhớ ngoài không gian bộ nhớ được gán sẽ trong trường hợp này dẫn đến lỗi chương trình (thường là lỗi phân đoạn hoặc lỗi bảo vệ).

+0

Vì vậy, một số hệ điều hành cho phép loại xâm nhập trắng trợn vào không gian bộ nhớ của các ứng dụng khác và/hoặc bản thân hệ điều hành? –

+0

http://en.wikipedia.org/wiki/Memory_protection – wroniasty

+0

Ah ok. Vì vậy, với bộ nhớ ảo, tôi có thể không "vô tình" sụp đổ các chương trình khác hoặc hệ điều hành? –

1

Hệ thống có Bộ quản lý bộ nhớ (MMU) rất có khả năng không cho phép bạn truy cập bộ nhớ tùy ý. Mọi hệ điều hành hiện đại đều sử dụng bảo vệ bộ nhớ. Nhưng trong lĩnh vực nhúng có nhiều hệ điều hành không sử dụng bảo vệ bộ nhớ và nơi nó thực sự có thể truy cập vào bất kỳ bộ nhớ địa chỉ nào.

1

Nếu tôi được tự gán một địa chỉ bộ nhớ cho một biến trong C, và sau đó cố gắng echo ra giá trị mà ... sao tôi có thể truy cập không hạn chế để xem bất cứ điều gì trong bộ nhớ hay có những hạn chế tại chỗ ?

Ngôn ngữ C vui mừng cho phép bạn thử điều đó, nhưng hầu hết các hệ điều hành sẽ không cho phép bạn truy cập bộ nhớ bên ngoài không gian bộ nhớ của quá trình. Nếu bạn đang viết mã cho một hệ thống nhúng mà không có nhiều giữa mã của bạn và phần cứng, bạn có thể sẽ đọc và ghi vào bất kỳ vị trí nào bạn muốn. Tuy nhiên, nếu bạn đang viết mã cho một hệ thống có bộ nhớ được bảo vệ, không nhiều lắm.

tôi đoán rằng sẽ sụp đổ khủng khiếp nếu những gì là tại địa chỉ đó không phù hợp với kích thước của kiểu char

Nah ... trình biên dịch không quan tâm những gì loại dữ liệu được lưu trữ tại bất kỳ địa chỉ cụ thể nào. Khi bạn nói (char *)0x28ff44, bạn đang nói rằng 0x28ff44char * và đủ tốt cho trình biên dịch. Tuy nhiên, mã của bạn vẫn có thể bị lỗi vì các lý do khác, như thể 0x28ff44 không phải là địa chỉ hợp lệ.

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