Exercise 2: A Write That Spans Three Pages — Possible Solution ==================================================================== THE TEST ------------------------------ mem = PhysicalMemoryFramed(num_frames=8) pt = PageTable(page_size=64) pt.map_page(vpn=0, pfn=6) pt.map_page(vpn=1, pfn=1) pt.map_page(vpn=2, pfn=4) start = 64 - 5 # 5 bytes left in page 0, all of page 1, then part of page 2 payload = bytes(range(80)) # 5 + 64 + 11 = 80 bytes total write_paged(mem, pt, start, payload) part0 = bytes(mem.data[6*64+59 : 6*64+64]) # the last 5 bytes of frame 6 part1 = bytes(mem.data[1*64+0 : 1*64+64]) # all 64 bytes of frame 1 part2 = bytes(mem.data[4*64+0 : 4*64+11]) # the first 11 bytes of frame 4 reconstructed = part0 + part1 + part2 RESULT ------------------------------ reconstructed bytes across all three (non-adjacent) frames match the original: True Reassembling the three separately-written pieces -- read directly from their own real physical frames, not through the page table -- produces exactly the original 80-byte payload, in the original order. WHY THE SAME write_paged() FUNCTION HANDLES THREE PAGES CORRECTLY ------------------------------ write_paged()'s own loop doesn't special-case "two pages" anywhere -- it just keeps chunking and translating until every byte of the input has been placed: pos = 0 while pos < len(data): current_vaddr = vaddr + pos offset_in_page = current_vaddr % mem.page_size bytes_left_in_page = mem.page_size - offset_in_page chunk_size = min(bytes_left_in_page, len(data) - pos) paddr = page_table.translate(current_vaddr) mem.data[paddr:paddr + chunk_size] = data[pos:pos + chunk_size] pos += chunk_size Each iteration only ever looks at "how many bytes are left until the NEXT page boundary" -- it has no built-in assumption about how many total boundaries the write will cross. For this test: iteration 1 writes 5 bytes (finishing page 0), iteration 2 writes 64 bytes (finishing page 1 entirely, since bytes_left_in_page is a full page right at that boundary), iteration 3 writes the remaining 11 bytes into page 2 -- and then pos == len(data), so the loop stops. WHY THIS GENERALIZES TO ANY NUMBER OF PAGES ------------------------------ Because each loop iteration only reasons about the CURRENT page boundary, not the total shape of the write, the exact same logic would correctly handle a write spanning 10 pages, or 100, with zero code changes -- the loop simply runs more iterations. Finding 4's own two-page example wasn't a special case this fix was narrowly built for; it was the smallest example that could demonstrate the general fix. WHY THIS WORKS AS AN ANSWER ------------------------------ Deliberately choosing a payload size (80 bytes) and starting offset that force a full middle page in addition to two partial edge pages tests a genuinely different shape than Finding 4's own two-page example, and confirms write_paged()'s own correctness isn't an artifact of that specific two-page case.