หากต้องการตอบคำถามที่คุณโพสต์ไว้ในความคิดเห็นหลายข้อ (ซึ่งฉันคิดว่าคุณควรแก้ไขในโพสต์ของคุณ):
สิ่งที่ฉันไม่เข้าใจคือคอมพิวเตอร์รู้ได้อย่างไรว่ามันช่วยให้เมื่ออ่านค่าของตัวแปรจากและที่อยู่เช่น 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ฉันจะถือว่าไบต์ใช้ได้ต่อไปเป็นตัวแปรถ่าน
โปรแกรม: ฉันจะเขียนให้กับตัวแปรay
โปรแกรม: ฉันต้องการที่จะแสดงเนื้อหาของ y
อ่านค่าในจุดหน่วยความจำที่สอง
ใช้ไลบรารีเพื่อแปลงจากไบต์เป็นอักขระ
ใช้ไลบรารีกราฟิกเพื่อเปลี่ยนหน้าจอคอนโซล (ตั้งค่าพิกเซลจากขาวดำเลื่อนหนึ่งบรรทัด ฯลฯ )
(และจากที่นี่)
สิ่งที่คุณอาจจะได้รับการแขวนบนเป็น - สิ่งที่เกิดขึ้นเมื่อจุดแรกในความทรงจำไม่มีอีกต่อไปx? หรือครั้งที่สองจะไม่มีอีกต่อไปy? เกิดอะไรขึ้นเมื่อมีคนอ่านxเป็นcharหรือyเป็นตัวชี้? ในระยะสั้นสิ่งเลวร้ายเกิดขึ้น สิ่งเหล่านี้บางอย่างมีพฤติกรรมที่ชัดเจนและบางอย่างมีพฤติกรรมที่ไม่ได้กำหนด พฤติกรรมที่ไม่ได้กำหนดเป็นสิ่งที่แน่นอน - ทุกสิ่งสามารถเกิดขึ้นได้จากอะไรไปจนถึงการหยุดทำงานของโปรแกรมหรือระบบปฏิบัติการ แม้แต่พฤติกรรมที่กำหนดไว้อย่างดีก็อาจเป็นอันตรายได้ หากฉันสามารถเปลี่ยนxเป็นตัวชี้ไปยังโปรแกรมของฉันและทำให้โปรแกรมของคุณใช้เป็นตัวชี้ได้ฉันสามารถให้โปรแกรมของคุณเริ่มต้นใช้งานโปรแกรมของฉัน - ซึ่งเป็นสิ่งที่แฮ็คเกอร์ทำ คอมไพเลอร์อยู่ที่นั่นเพื่อช่วยให้แน่ใจว่าเราไม่ได้ใช้int xเป็นstringและสิ่งต่าง ๆ ในธรรมชาตินั้น รหัสเครื่องนั้นไม่ได้รับรู้ถึงประเภทและจะทำตามคำแนะนำที่บอกให้ทำเท่านั้น นอกจากนี้ยังมีข้อมูลจำนวนมากที่ค้นพบในขณะใช้งาน: หน่วยความจำไบต์ใดบ้างที่โปรแกรมอนุญาตให้ใช้? ไม่xเริ่มต้นที่ไบต์แรกหรือ 12?
แต่คุณสามารถจินตนาการได้ว่าการเขียนโปรแกรมแบบนี้น่ากลัวแค่ไหน (และคุณสามารถทำได้ในภาษาแอสเซมบลี) คุณเริ่มต้นด้วย 'ประกาศ' ตัวแปรของคุณ - คุณบอกตัวเองว่าไบต์ 1 xไบต์ 2 yและตามที่คุณเขียนแต่ละบรรทัดของรหัสโหลดและจัดเก็บลงทะเบียนคุณ (เป็นมนุษย์) ต้องจำไว้เป็นที่หนึ่งxและที่ สิ่งหนึ่งคือyเพราะระบบไม่มีความคิด และคุณ (ในฐานะมนุษย์) ต้องจำประเภทxและyเป็นเพราะอีกครั้ง - ระบบไม่มีความคิด