Để giải quyết câu hỏi bạn đã đăng trong một số bình luận (mà tôi nghĩ bạn nên chỉnh sửa thành bài đăng của mình):
Điều tôi không hiểu là làm thế nào máy tính biết cho phép khi nó đọc giá trị của biến và địa chỉ như 10001 nếu là int hoặc char. Hãy tưởng tượng tôi nhấp vào một chương trình gọi là anyprog.exe. Ngay lập tức mã bắt đầu thực thi. Tập tin exe này có bao gồm thông tin về việc các biến được lưu trữ như trong hoặc char không?
Vì vậy, hãy đặt một số mã cho nó. Hãy nói rằng bạn viết:
int x = 4;
Và hãy giả sử rằng nó được lưu trữ trong RAM:
0x00010004: 0x00000004
Phần đầu tiên là địa chỉ, phần thứ hai là giá trị. Khi chương trình của bạn (thực thi dưới dạng mã máy) chạy, tất cả những gì nó thấy 0x00010004
là giá trị 0x000000004
. Nó không 'biết' loại dữ liệu này và cũng không biết nó được sử dụng như thế nào.
Vì vậy, làm thế nào để chương trình của bạn tìm ra điều đúng đắn để làm? Hãy xem xét mã này:
int x = 4;
x = x + 5;
Chúng tôi có một đọc và viết ở đây. Khi chương trình của bạn đọc x
từ bộ nhớ, nó tìm thấy 0x00000004
ở đó. Và chương trình của bạn biết để thêm 0x00000005
vào nó. Và lý do chương trình của bạn 'biết' đây là một hoạt động hợp lệ, là bởi vì trình biên dịch đảm bảo rằng hoạt động đó là hợp lệ thông qua loại an toàn. Trình biên dịch của bạn đã xác minh rằng bạn có thể thêm 4
và 5
cùng nhau. Vì vậy, khi mã nhị phân của bạn chạy (exe), nó không phải thực hiện xác minh đó. Nó chỉ thực hiện từng bước một cách mù quáng, giả sử mọi thứ đều ổn (những điều tồi tệ xảy ra khi chúng thực tế, không ổn).
Một cách khác để nghĩ về nó là như thế này. Tôi cung cấp cho bạn thông tin này:
0x00000004: 0x12345678
Cùng định dạng như trước - địa chỉ bên trái, giá trị bên phải. Loại nào là giá trị? Tại thời điểm này, bạn biết nhiều thông tin về giá trị đó như máy tính của bạn khi thực thi mã. Nếu tôi bảo bạn thêm 12743 vào giá trị đó, bạn có thể làm điều đó. Bạn không biết tác động của hoạt động đó sẽ là gì trên toàn hệ thống, nhưng thêm hai số là điều bạn thực sự giỏi, vì vậy bạn có thể thực hiện nó. Điều đó làm cho giá trị một int
? Không nhất thiết - Tất cả những gì bạn thấy là hai giá trị 32 bit và toán tử cộng.
Có lẽ một số nhầm lẫn sau đó nhận được dữ liệu trở lại. Nếu chúng ta có:
char A = 'a';
Làm thế nào để máy tính biết hiển thị a
trong giao diện điều khiển? Vâng, có rất nhiều bước để đó. Đầu tiên là đi đến A
vị trí của bộ nhớ và đọc nó:
0x00000004: 0x00000061
Giá trị hex cho a
ASCII là 0x61, do đó, ở trên có thể là thứ bạn thấy trong bộ nhớ. Vì vậy, bây giờ mã máy của chúng tôi biết giá trị số nguyên. Làm thế nào để nó biết để biến giá trị số nguyên thành một ký tự để hiển thị nó? Nói một cách đơn giản, trình biên dịch đảm bảo đưa vào tất cả các bước cần thiết để thực hiện quá trình chuyển đổi đó. Nhưng chính máy tính của bạn (hoặc chương trình / exe) không biết loại dữ liệu đó là gì. Giá trị 32 bit đó có thể là bất cứ thứ gì - int
,, char
một nửa của double
một con trỏ, một phần của một mảng, một phần của một string
phần của một lệnh, v.v.
Đây là một tương tác ngắn mà chương trình của bạn (exe) có thể có với máy tính / hệ điều hành.
Chương trình: Tôi muốn khởi nghiệp. Tôi cần 20 MB bộ nhớ.
Hệ điều hành: tìm thấy 20 MB bộ nhớ miễn phí không sử dụng và trao chúng
(Các lưu ý quan trọng là điều này có thể trở lại bất kỳ 20 MB bộ nhớ, họ thậm chí không phải là tiếp giáp. Tại thời điểm này, chương trình bây giờ có thể hoạt động trong bộ nhớ nó có mà không nói chuyện với các hệ điều hành)
Chương trình: Tôi sẽ giả định rằng vị trí đầu tiên trong bộ nhớ là biến số nguyên 32 bit x
.
(Trình biên dịch đảm bảo rằng việc truy cập vào các biến khác sẽ không bao giờ chạm vào điểm này trong bộ nhớ. Không có gì trên hệ thống cho biết byte đầu tiên là biến x
hoặc biến đó x
là một số nguyên. Tương tự: bạn có một túi. Bạn nói với mọi người rằng bạn sẽ chỉ để những quả bóng màu vàng trong chiếc túi này. Khi ai đó sau đó rút thứ gì đó ra khỏi túi, thì sẽ rất sốc khi họ lấy ra thứ gì đó màu xanh hoặc hình khối - một cái gì đó đã sai lầm khủng khiếp. chương trình hiện đang giả sử vị trí bộ nhớ đầu tiên là biến x và đó là một số nguyên. Nếu một thứ khác được ghi trên byte bộ nhớ này hoặc nó được coi là một thứ khác - điều gì đó khủng khiếp đã xảy ra. Trình biên dịch đảm bảo các loại điều này không xảy ra. không xảy ra)
Chương trình: Bây giờ tôi sẽ ghi 2
vào bốn byte đầu tiên mà tôi giả sử x
là tại.
Chương trình: Tôi muốn thêm 5 vào x
.
Đọc giá trị của X vào một thanh ghi tạm thời
Thêm 5 vào sổ đăng ký tạm thời
Lưu trữ giá trị của thanh ghi tạm thời trở lại byte đầu tiên, vẫn được giả sử là x
.
Chương trình: Tôi sẽ giả sử byte có sẵn tiếp theo là biến char y
.
Chương trình: Tôi sẽ viết a
vào biến y
.
Chương trình: Tôi muốn hiển thị nội dung của y
Đọc giá trị ở vị trí bộ nhớ thứ hai
Sử dụng một thư viện để chuyển đổi từ byte thành ký tự
Sử dụng các thư viện đồ họa để thay đổi màn hình bảng điều khiển (cài đặt pixel từ đen sang trắng, cuộn một dòng, v.v.)
(Và nó tiếp tục từ đây)
Những gì bạn có thể bị treo lên là - điều gì xảy ra khi vị trí đầu tiên trong bộ nhớ không còn nữa x
? hay cái thứ hai không còn nữa y
? Điều gì xảy ra khi ai đó đọc x
như một char
hoặc y
một con trỏ? Trong ngắn hạn, những điều xấu xảy ra. Một số trong những điều này có hành vi được xác định rõ, và một số có hành vi không xác định. Hành vi không xác định chính xác là như vậy - bất cứ điều gì cũng có thể xảy ra, từ không có gì, đến việc làm hỏng chương trình hoặc hệ điều hành. Ngay cả hành vi được xác định rõ cũng có thể độc hại. Nếu tôi có thể thay đổi x
thành một con trỏ tới chương trình của mình và để chương trình của bạn sử dụng nó làm con trỏ, thì tôi có thể khiến chương trình của bạn bắt đầu thực hiện chương trình của mình - đó chính xác là những gì tin tặc làm. Trình biên dịch có mặt để giúp đảm bảo chúng tôi không sử dụng int x
như mộtstring
và những thứ thuộc về bản chất đó Bản thân mã máy không biết các loại và nó sẽ chỉ làm những gì hướng dẫn bảo nó làm. Ngoài ra còn có một lượng lớn thông tin được phát hiện vào thời gian chạy: byte nào của bộ nhớ là chương trình được phép sử dụng? Có x
bắt đầu ở byte đầu tiên hoặc ngày 12 không?
Nhưng bạn có thể tưởng tượng sẽ kinh khủng thế nào khi thực sự viết các chương trình như thế này (và bạn có thể, bằng ngôn ngữ lắp ráp). Bạn bắt đầu bằng cách 'khai báo' các biến của mình - bạn tự nói với mình rằng byte 1 là x
, byte 2 là y
và khi bạn viết từng dòng mã, tải và lưu trữ các thanh ghi, bạn (như một con người) phải nhớ đó là x
cái nào và cái nào một là y
, bởi vì hệ thống không có ý tưởng. Và bạn (như một con người) phải nhớ những loại x
và y
là gì, bởi vì một lần nữa - hệ thống không có ý tưởng.