หากต้องการตอบคำถามที่คุณโพสต์ไว้ในความคิดเห็นหลายข้อ (ซึ่งฉันคิดว่าคุณควรแก้ไขในโพสต์ของคุณ):
สิ่งที่ฉันไม่เข้าใจคือคอมพิวเตอร์รู้ได้อย่างไรว่ามันช่วยให้เมื่ออ่านค่าของตัวแปรจากและที่อยู่เช่น 10001 ถ้าเป็น int หรืออักขระ ลองนึกภาพฉันคลิกที่โปรแกรมที่ชื่อว่า anyprog.exe รหัสทันทีเริ่มดำเนินการ ไฟล์ exe นี้มีข้อมูลเกี่ยวกับว่าตัวแปรถูกเก็บไว้ในหรือไม่?
ดังนั้นให้ใส่รหัสลงไป สมมติว่าคุณเขียน:
int x = 4;
และสมมติว่ามันถูกเก็บไว้ใน RAM:
0x00010004: 0x00000004
ส่วนแรกเป็นที่อยู่ส่วนที่สองเป็นค่า เมื่อโปรแกรมของคุณ (ที่รันเป็นรหัสเครื่อง) วิ่งทั้งหมดก็เห็นที่เป็นค่า0x00010004
0x000000004
ไม่ทราบชนิดของข้อมูลนี้และไม่ทราบว่าควรใช้อย่างไร
ดังนั้นโปรแกรมของคุณจะหาสิ่งที่ถูกต้องอย่างไร พิจารณารหัสนี้:
int x = 4;
x = x + 5;
เราได้อ่านและเขียนที่นี่ เมื่อโปรแกรมของคุณอ่านx
จากหน่วยความจำจะพบว่า0x00000004
มี และโปรแกรมของคุณรู้ที่จะเพิ่ม0x00000005
เข้าไป และเหตุผลที่โปรแกรมของคุณ 'รู้' นี่คือการทำงานที่ถูกต้องเพราะคอมไพเลอร์ตรวจสอบให้แน่ใจว่าการทำงานนั้นถูกต้องผ่านประเภทความปลอดภัย คอมไพเลอร์ของคุณได้รับการยืนยันแล้วว่าคุณสามารถเพิ่ม4
และ5
ร่วมกัน ดังนั้นเมื่อรหัสไบนารี่ของคุณทำงาน (exe) ก็ไม่จำเป็นต้องทำการยืนยัน มันดำเนินการแต่ละขั้นสุ่มสี่สุ่มห้าโดยสมมติว่าทุกอย่างเรียบร้อย (สิ่งเลวร้ายเกิดขึ้นเมื่อพวกเขาอยู่ในความเป็นจริงไม่ใช่ตกลง)
อีกวิธีที่จะคิดว่ามันเป็นเช่นนี้ ฉันให้ข้อมูลนี้กับคุณ:
0x00000004: 0x12345678
รูปแบบเดียวกับก่อน - ที่อยู่ทางด้านซ้ายค่าทางด้านขวา ค่าประเภทใด ณ จุดนี้คุณจะรู้ข้อมูลมากพอ ๆ กับค่านั้นตามที่คอมพิวเตอร์ของคุณทำเมื่อมันประมวลผลโค้ด ถ้าฉันบอกให้คุณเพิ่ม 12743 ลงในค่านั้นคุณก็ทำได้ คุณไม่มีความคิดว่าผลกระทบของการดำเนินการนั้นจะเกิดขึ้นในทั้งระบบ แต่การเพิ่มตัวเลขสองจำนวนเป็นสิ่งที่คุณทำได้ดีมากดังนั้นคุณสามารถทำได้ สิ่งนี้ทำให้คุณค่าint
หรือไม่? ไม่จำเป็น - ทั้งหมดที่คุณเห็นคือค่า 32 บิตสองค่าและตัวดำเนินการเพิ่ม
บางทีความสับสนบางอย่างอาจทำให้ข้อมูลกลับมา ถ้าเรามี:
char A = 'a';
คอมพิวเตอร์รู้ได้อย่างไรว่าจะแสดงa
ในคอนโซล? มีขั้นตอนมากมายในการทำเช่นนั้น วิธีแรกคือไปที่A
ตำแหน่ง s ในหน่วยความจำและอ่าน:
0x00000004: 0x00000061
ค่าฐานสิบหกสำหรับa
ใน ASCII คือ 0x61 ดังนั้นด้านบนอาจเป็นสิ่งที่คุณเห็นในหน่วยความจำ ดังนั้นตอนนี้รหัสเครื่องของเรารู้ค่าจำนวนเต็ม จะทราบได้อย่างไรว่าการเปลี่ยนค่าจำนวนเต็มเป็นอักขระเพื่อแสดงมัน เพียงแค่ใส่คอมไพเลอร์ตรวจสอบให้แน่ใจว่าได้ใส่ขั้นตอนที่จำเป็นทั้งหมดเพื่อทำการเปลี่ยนแปลงนั้น แต่คอมพิวเตอร์ของคุณเอง (หรือโปรแกรม / exe) ไม่ทราบว่าเป็นข้อมูลประเภทใด ค่า 32 บิตนั้นอาจเป็นอะไรก็ได้ - int
,, char
ครึ่งหนึ่งของ a double
, ตัวชี้, ส่วนหนึ่งของอาร์เรย์, ส่วนของ a string
, ส่วนหนึ่งของคำสั่ง ฯลฯ
นี่เป็นการโต้ตอบสั้น ๆ ที่โปรแกรมของคุณ (exe) อาจมีกับคอมพิวเตอร์ / ระบบปฏิบัติการ
โปรแกรม: ฉันต้องการเริ่มต้น ฉันต้องการหน่วยความจำ 20 MB
ระบบปฏิบัติการ: ค้นหาหน่วยความจำฟรี 20 MB ที่ไม่ได้ใช้งานและส่งมอบให้
(หมายเหตุสำคัญคือสิ่งนี้สามารถคืนหน่วยความจำ 20 MB ใด ๆได้โดยไม่ต้องต่อเนื่องกัน ณ จุดนี้โปรแกรมสามารถทำงานภายในหน่วยความจำที่มีโดยไม่ต้องพูดคุยกับระบบปฏิบัติการ)
โปรแกรม: x
ฉันจะคิดว่าจุดแรกในความทรงจำเป็นตัวแปรจำนวนเต็ม
(คอมไพเลอร์ทำให้แน่ใจว่าการเข้าถึงตัวแปรอื่น ๆ จะไม่แตะต้องจุดนี้ในหน่วยความจำไม่มีอะไรในระบบที่บอกว่าไบต์แรกคือตัวแปรx
หรือตัวแปรx
นั้นเป็นจำนวนเต็มการเปรียบเทียบ: คุณมีกระเป๋าคุณบอกคนอื่นว่า คุณจะเอาลูกบอลสีเหลืองใส่ในกระเป๋าใบนี้เมื่อมีใครบางคนดึงบางสิ่งออกจากกระเป๋าในเวลาต่อมามันจะน่าตกใจที่พวกเขาจะดึงบางสิ่งออกเป็นสีน้ำเงินหรือลูกบาศก์ - มีบางอย่างผิดพลาดไปอย่างน่ากลัว ตอนนี้โปรแกรมสันนิษฐานว่าหน่วยความจำจุดแรกคือตัวแปร x และเป็นจำนวนเต็มหากมีสิ่งอื่นใดที่เคยเขียนบนหน่วยความจำไบต์นี้หรือสันนิษฐานว่าเป็นอย่างอื่น - สิ่งที่น่ากลัวเกิดขึ้นคอมไพเลอร์มั่นใจว่าสิ่งเหล่านี้ จะไม่เกิดขึ้น)
โปรแกรม: ตอนนี้ฉันจะเขียน2
ถึงสี่ไบต์แรกที่ฉันคิดว่าx
อยู่ที่
โปรแกรม: ฉันต้องการเพิ่ม 5 x
ถึง
อ่านค่า X ลงในการลงทะเบียนชั่วคราว
เพิ่ม 5 ไปยังการลงทะเบียนชั่วคราว
x
ร้านคุ้มค่าของการลงทะเบียนชั่วคราวกลับเข้ามาในไบต์แรกซึ่งจะถือว่ายังคงเป็น
โปรแกรม: y
ฉันจะถือว่าไบต์ใช้ได้ต่อไปเป็นตัวแปรถ่าน
โปรแกรม: ฉันจะเขียนให้กับตัวแปรa
y
โปรแกรม: ฉันต้องการที่จะแสดงเนื้อหาของ y
อ่านค่าในจุดหน่วยความจำที่สอง
ใช้ไลบรารีเพื่อแปลงจากไบต์เป็นอักขระ
ใช้ไลบรารีกราฟิกเพื่อเปลี่ยนหน้าจอคอนโซล (ตั้งค่าพิกเซลจากขาวดำเลื่อนหนึ่งบรรทัด ฯลฯ )
(และจากที่นี่)
สิ่งที่คุณอาจจะได้รับการแขวนบนเป็น - สิ่งที่เกิดขึ้นเมื่อจุดแรกในความทรงจำไม่มีอีกต่อไปx
? หรือครั้งที่สองจะไม่มีอีกต่อไปy
? เกิดอะไรขึ้นเมื่อมีคนอ่านx
เป็นchar
หรือy
เป็นตัวชี้? ในระยะสั้นสิ่งเลวร้ายเกิดขึ้น สิ่งเหล่านี้บางอย่างมีพฤติกรรมที่ชัดเจนและบางอย่างมีพฤติกรรมที่ไม่ได้กำหนด พฤติกรรมที่ไม่ได้กำหนดเป็นสิ่งที่แน่นอน - ทุกสิ่งสามารถเกิดขึ้นได้จากอะไรไปจนถึงการหยุดทำงานของโปรแกรมหรือระบบปฏิบัติการ แม้แต่พฤติกรรมที่กำหนดไว้อย่างดีก็อาจเป็นอันตรายได้ หากฉันสามารถเปลี่ยนx
เป็นตัวชี้ไปยังโปรแกรมของฉันและทำให้โปรแกรมของคุณใช้เป็นตัวชี้ได้ฉันสามารถให้โปรแกรมของคุณเริ่มต้นใช้งานโปรแกรมของฉัน - ซึ่งเป็นสิ่งที่แฮ็คเกอร์ทำ คอมไพเลอร์อยู่ที่นั่นเพื่อช่วยให้แน่ใจว่าเราไม่ได้ใช้int x
เป็นstring
และสิ่งต่าง ๆ ในธรรมชาตินั้น รหัสเครื่องนั้นไม่ได้รับรู้ถึงประเภทและจะทำตามคำแนะนำที่บอกให้ทำเท่านั้น นอกจากนี้ยังมีข้อมูลจำนวนมากที่ค้นพบในขณะใช้งาน: หน่วยความจำไบต์ใดบ้างที่โปรแกรมอนุญาตให้ใช้? ไม่x
เริ่มต้นที่ไบต์แรกหรือ 12?
แต่คุณสามารถจินตนาการได้ว่าการเขียนโปรแกรมแบบนี้น่ากลัวแค่ไหน (และคุณสามารถทำได้ในภาษาแอสเซมบลี) คุณเริ่มต้นด้วย 'ประกาศ' ตัวแปรของคุณ - คุณบอกตัวเองว่าไบต์ 1 x
ไบต์ 2 y
และตามที่คุณเขียนแต่ละบรรทัดของรหัสโหลดและจัดเก็บลงทะเบียนคุณ (เป็นมนุษย์) ต้องจำไว้เป็นที่หนึ่งx
และที่ สิ่งหนึ่งคือy
เพราะระบบไม่มีความคิด และคุณ (ในฐานะมนุษย์) ต้องจำประเภทx
และy
เป็นเพราะอีกครั้ง - ระบบไม่มีความคิด