5.1.5 · D3 · Hardware › Instruction Set Architecture (ISA) › x86 architecture overview
Intuition Yeh page kya hai
Parent x86 overview ne tumhe kaise kaam karta hai yeh bataya. Yahan hum har woh case cover karte hain jo do bade x86 skills mein aa sakta hai: address arithmetic (segment × 16 + offset, har regime mein) aur register windows (RAX → EAX → AX → AL, including traps). Pehle hum scenarios enumerate karte hain, phir har scenario ka ek example karte hain — tumhe har answer se pehle forecast karna hoga.
Do prerequisite ideas jinpe hum rely karte hain, dono neeche scratch se build ki gayi hain taaki koi symbol unfamiliar na lage:
Ek hex digit 0 , 1 , … , 9 , A , … , F mein se ek hai — solah values, yaani exactly 4 bits (kyunki 2 4 = 16 ). Yehi wajah hai ki x86 ko hex pasand hai: ek hex digit = ek nibble = 4 wires.
Shift-left-by-n jo x ≪ n likha jaata hai, matlab hai "x ki binary form ke right end mein n zero-bits jod do," jo value ko 2 n se multiply karta hai. Toh ≪ 4 matlab × 16 hai, yaani "ek hex zero append karo."
Neeche do plain math shorthand use hote hain — yeh unka matlab hai taaki koi symbol surprise na kare:
[ a , b ] (ek interval ) shorthand hai "har value a se b tak, endpoints shamil." Toh x ∈ [ 0 , 3 ] ka matlab sirf 0 ≤ x ≤ 3 hai.
x mod m (modulo ) matlab hai "x mein se m ke poore copies nikaalke jo remainder bachta hai" — yaani jab x , m size ke ek wheel par wrap around kar chuka ho tab kya bachta hai. Example ke liye 0x100000 mod 0x100000 = 0 kyunki yeh exactly ek baar wrap karke start pe aa jaata hai.
Is topic ki har cheez inhi cells mein se ek hai. Neeche har worked example us cell ke saath tagged hai jo woh cover karta hai, taaki end tak koi cell unseen na rahe.
#
Case class
Isme kya special hai
Example
A
Address: ordinary case
segment & offset dono nonzero, koi wrap nahi
Ex 1
B
Address: zero degenerate
offset = 0 , ya segment = 0
Ex 2
C
Address: overlap / aliasing
do alag (seg, off) pairs → same byte
Ex 3
D
Address: wrap-around / limit
sum 20 bits se zyada (≥ 1 MB)
Ex 4
E
Register: ordinary window read
RAX mein se EAX/AX/AL/AH nikaalana
Ex 5
F
Register: partial-write trap
EAX likhne se upper 32 zero ho jaate hain; AL/AH/AX/RAX writes alag behave karti hain
Ex 6
G
Word problem (real world)
"kya yeh .COM file fit hogi?"
Ex 7
H
Exam twist
instruction-length reasoning + ek "gotcha" address
Ex 8
Neeche, 0x prefix wale saare numbers hexadecimal (base 16) hain; baaki sab decimal hain.
Worked example Ex 1 (Cell A) — plain physical address
Real mode. Segment = 0x2F00 , Offset = 0x0140 . Physical byte address nikalo.
Forecast: aage padhne se pehle leading hex digits guess karo — kya yeh 0x2F1... kuch ke paas hai?
Segment ko 4 bits left shift karo (× 16 ): 0x2F00 ≪ 4 = 0x2F000 .
Yeh step kyun? Segment ek 16-byte-aligned "paragraph" ko name karta hai. 16 se multiply karne se 16-bit segment ek 20-bit address ke top 16 bits ban jaata hai; trailing hex 0 append hone wala nibble hai (neeche figure dekho).
Offset add karo : 0x2F000 + 0x0140 = 0x2F140 .
Yeh step kyun? Offset segment ki window ke andar exact byte select karta hai, isliye yeh low bits fill karta hai.
Answer: 0x2F140.
Verify: result [ seg × 16 , seg × 16 + 0xFFFF ] = [ 0x2F000 , 0x3EFFF ] mein hona chahiye. Sach mein 0x2F140 iske andar fit hota hai. ✓
Neeche ki figure literally assembly dikhati hai: dekho yellow box ek trailing 0 kaise gain karta hai (woh ≪ 4 hai), phir green offset low nibbles mein kaise aata hai, aur red result 0x2F140 milta hai.
Worked example Ex 2 (Cell B) — offset zero, phir segment zero
(i) Segment = 0x1000 , Offset = 0x0000 . (ii) Segment = 0x0000 , Offset = 0x0400 .
Forecast: jab ek input 0 ho, kya formula break hota hai? Dono answers predict karo.
(i) 0x1000 ≪ 4 + 0 = 0x10000 + 0 = 0x10000 .
Yeh step kyun? Offset 0 matlab "segment ki bilkul pehli byte." Kuch degenerate nahi hota — formula total hai, yeh zero ko kisi bhi doosri value ki tarah handle karta hai.
(ii) 0x0000 ≪ 4 + 0x0400 = 0 + 0x0400 = 0x00400 .
Yeh step kyun? Segment 0 matlab "window physical address 0 se shuru hoti hai," toh offset hi physical address hai. Exactly aise CPU low interrupt-vector table tak pahuncha karta hai.
Answers: (i) 0x10000, (ii) 0x00400.
Verify: dono < 1 MB = 0x100000 hain, toh koi wrap nahi. Aur (ii) apne offset ke barabar hai — "segment 0" ka sanity check. ✓
Common mistake "Segment 0 illegal / meaningless hai."
Kyun sahi lagta hai: zero often "empty" ya "invalid" mean karta hai.
Fix: segment 0 bilkul legal hai; yeh sirf window ko physical 0 pe anchor karta hai. Interrupt vector table literally wahan rehti hai.
Intuition Do names, ek byte
Kyunki ek segment 16-byte steps mein slide karta hai lekin ek offset 65536 bytes roam kar sakta hai, bahut saare alag (segment, offset) pairs ek hi physical byte point karte hain. Yeh address aliasing hai, ek genuine 8086 hazard.
Worked example Ex 3 (Cell C) — prove karo ki do pairs alias karte hain
Dikhao ki 0x1234:0x0005 aur 0x1230:0x0045 same byte hit karte hain. (Notation seg:off.)
Forecast: compute karne se pehle guess karo ki yeh collide karte hain ya nahi.
Pehla pair: 0x1234 ≪ 4 + 0x0005 = 0x12340 + 0x0005 = 0x12345 .
Yeh step kyun? Standard formula — target byte establish karta hai.
Doosra pair: 0x1230 ≪ 4 + 0x0045 = 0x12300 + 0x0045 = 0x12345 .
Yeh step kyun? Humne segment 4 se kam kiya (four paragraphs) aur offset 0x40 se badhaaya (64 bytes) — yeh dono changes cancel ho jaate hain kyunki 4 paragraphs down = 4 × 16 = 64 bytes = 0x40 up. Yeh exactly balance karte hain.
Dono = 0x12345 — yeh alias karte hain.
Verify: physical addresses ka difference 0 hona chahiye: 0x12345 − 0x12345 = 0 . ✓ Offset sirf 16 bits span karta hai (0x0000–0xFFFF), isliye kisi bhi physical byte ke up to ⌊ 65536/16 ⌋ = 4096 alag names ho sakte hain — ek huge overlap web.
Neeche ki figure single red target byte 0x12345 ko ek physical number line par plot karti hai, blue pair (base 0x12340 se chhota +0x05 hop) aur green pair (base 0x12300 se lamba +0x45 hop) dono usi par pahunchte hain — do arrows, ek landing spot.
Intuition Top ke baad kya hota hai?
Real-mode adder ek aisi value produce kar sakta hai jo 0xFFFF × 16 + 0xFFFF = 0x10FFEF tak pahunch sakti hai — yeh 1 MB se aage hai. Original 8086 par sirf 20 address wires the, toh bit 20 gir jaata tha aur address 0 par wrap ho jaata tha (famous "A20" story). Hum ise "result modulo 2 20 lo" treat karte hain (upar modulo reminder dekho).
Worked example Ex 4 (Cell D) — wrap force karo
Segment = 0xFFFF , Offset = 0x0010 . Raw sum aur wrapped 20-bit address do jo 8086 actually use karta tha.
Forecast: raw sum 20 bits overflow karta hai — wrap ke baad kahan land karta hai?
Raw sum: 0xFFFF ≪ 4 + 0x0010 = 0xFFFF0 + 0x0010 = 0x100000 .
Yeh step kyun? 0xFFFF0 sabse high paragraph hai; 0x10 add karne se exactly 2 20 tak pahunch jaate hain.
20 bits tak wrap karo: 0x100000 mod 2 20 = 0x100000 − 0x100000 = 0x00000 .
Yeh step kyun? Sirf 20 wires exist karte hain (0x00000 –0xFFFFF ), toh 21st bit discard ho jaati hai — address bottom par roll over ho jaata hai.
Answers: raw 0x100000, wrapped 0x00000.
Verify: raw sum theoretical range [ 0 , 0x10FFEF ] mein hai ✓, aur 0x100000 mod 0x100000 = 0 ✓ — woh classic "high memory area" wrap jis par DOS rely karta tha.
Definition Register window
Names RAX / EAX / AX / AL same 64 physical bits hain, har name ek chhota low slice expose karta hai. Chhota name padhna = high bits mask off (throw away) karna. Koi data move nahi hota.
Worked example Ex 5 (Cell E) — register slice karo
RAX = 0xDEADBEEFCAFEBABE. EAX, AX, AL, aur AH padho.
Forecast: har name ke liye kaun se bytes survive karte hain?
EAX = low 32 bits = low 8 hex digits = 0xCAFEBABE.
Yeh step kyun? 32 bits = 8 nibbles = 8 hex digits right se, toh hum rightmost 8 digits rakhte hain aur baaki drop karte hain.
AX = low 16 bits = low 4 hex digits = 0xBABE.
Yeh step kyun? 16 bits = 4 nibbles = 4 hex digits, toh AX EAX se strictly chhota window hai — sirf rightmost 4 digits rakhte hain.
AL = low 8 bits = low 2 hex digits = 0xBE.
Yeh step kyun? 8 bits = 2 nibbles = 2 hex digits; AL lowest byte hai, toh sirf last two digits survive karte hain.
AH = bits 8–15 (doosra byte, lowest nahi) = 0xBA.
Yeh step kyun? AH odd wala hai: yeh AX ka high byte hai, yaani right se digits 3–4, 8086 ke split AX = AH:AL ka leftovers.
Answers: EAX 0xCAFEBABE, AX 0xBABE, AL 0xBE, AH 0xBA.
Verify: AX ko uske halves se rebuild karo: AH ≪ 8 + AL = 0xBA00 + 0xBE = 0xBABE ✓, step 2 se match karta hai.
Neeche ki figure RAX ke 16 hex digits stack karti hai aur right se har name ki window bracket karti hai: green EAX (8 digits), yellow AX (4), red AL (2), aur — low end se offset — orange AH bracket, jo vivid banata hai ki AH bottom par nahi hai.
Intuition x86 ka single most surprising rule
EAX mein likhne se zero-extend hota hai: yeh RAX ke top 32 bits clear kar deta hai. Lekin AX, AL, ya AH mein likhne se upper bits untouched rehte hain (yeh merge karte hain). Aur RAX mein likhne se saare 64 bits replace ho jaate hain. Yeh asymmetry sabko ek baar zaroor jaalaata hai. Reason: x86-64 ke designers ne 32-bit writes ko top clear karne diya pipeline help ke liye, lekin 8/16-bit writes ko merging rakhna pada 8086 compatibility ke liye — ek fossil ek modern rule se takra raha hai.
Worked example Ex 6 (Cell F) — har write width se upper bits track karo
Start karo RAX = 0x1122334455667788. Order mein apply karo:
mov eax, 0x0000000A; phir mov al, 0xFF; phir mov ah, 0x77; phir mov ax, 0xBEEF; phir mov rax, 0xCAFEF00DDEADBEEF. Har ek ke baad RAX do.
Forecast: predict karo ki 0x11223344 prefix har write se survive karega ya nahi, aur mov ah kaun sa byte touch karta hai.
mov eax, 0x0000000A (32-bit) → upper 32 zero hote hain : RAX = 0x000000000000000A.
Yeh step kyun? Zero-extend rule. Purana 0x11223344 hamesha ke liye gone.
mov al, 0xFF (8-bit low) → merges lowest byte, upper untouched: RAX = 0x00000000000000FF.
Yeh step kyun? AL sirf lowest byte replace karta hai (0A → FF ); 8-bit ke liye koi zero-extend nahi.
mov ah, 0x77 (8-bit high of AX ) → merges doosri byte, baaki sab untouched: RAX = 0x000000000000_77FF = 0x00000000000077FF.
Yeh step kyun? AH bits 8–15 write karta hai, yaani right se digits 3–4, AL (0xFF) aur saare higher bytes ko chhodta hai. Yeh missing 8-bit-offset case hai: ek 8-bit write jo bottom byte touch nahi karta .
mov ax, 0xBEEF (16-bit) → merges low 2 bytes: RAX = 0x000000000000BEEF.
Yeh step kyun? AX low 2 bytes ek saath replace karta hai (pehle waale AH=0x77 aur AL=0xFF dono overwrite karta hai); 16 se upar ke bits jaise the waise rehte hain (yahan sab zero hain).
mov rax, 0xCAFEF00DDEADBEEF (64-bit) → saare 64 bits replace hote hain : RAX = 0x0CAFEF00DDEADBEEF? Nahi — literal 15 hex digits ka hai, toh RAX = 0x0CAFEF00DDEADBEEF padded to 16 digits: RAX = 0x0CAFEF00DDEADBEEF.
Yeh step kyun? Full-width write mein merge ya zero-extend kuch nahi hota — yeh simply naya register hai. Yeh width spectrum ka top anchor karta hai (8 → 16 → 32 → 64).
Answers: 0x000000000000000A → 0x00000000000000FF → 0x00000000000077FF → 0x000000000000BEEF → 0x0CAFEF00DDEADBEEF.
Verify: AH write bits 8–15 ko 0x77 set karna chahiye jabki AL=0xFF rahe: ( 0x77 ≪ 8 ) + 0xFF = 0x7700 + 0xFF = 0x77FF ✓. Nonzero prefix se merge trap re-run karo RAX = 0xFFFFFFFF000000FF doing mov al, 0x11: merge deta hai 0xFFFFFFFF00000011, 0xFFFFFFFF rakhta hai ✓. Aur 64-bit write exactly literal ki value rakhta hai ✓.
mov al, x baki register clear kar deta hai jaise mov eax, x karta hai."
Kyun sahi lagta hai: 32-bit form top clear karta hai, toh assume karte ho ki saare partial forms aisa karte hain.
Fix: sirf 32-bit destination writes upper 32 bits zero karte hain. 8-bit (AL/AH) aur 16-bit (AX) writes existing register mein merge karte hain; 64-bit (RAX) writes sab kuch replace karte hain.
Definition CS aur PSP (do DOS terms jo hum use karne waale hain)
CS = Code Segment register , x86 ke segment registers mein se ek (parent note mein mention hai). Real mode mein yeh segment number hold karta hai jahan current program ka code rehta hai; us window ka physical base CS × 16 hai.
PSP = Program Segment Prefix , ek fixed 256-byte (0x100) header block jo DOS har loaded program ke bilkul front mein banata hai (command line, environment pointer, etc.). Tumhara code iske baad shuru hota hai, offset 0x100 par.
Worked example Ex 7 (Cell G) — kya
.COM program fit hoga?
Ek DOS .COM program CS = 0x0800 par load hota hai, aur saara code+data+stack ek 64 KB segment mein rehna chahiye. Program mein 0xFE00 bytes code hai, front mein 0x0100 bytes PSP header chahiye, aur top par 0x0200 bytes stack reserve karta hai. Kya yeh segment mein fit hota hai, aur uska last usable byte kaun sa physical address hai?
Forecast: add karne se pehle yes/no guess karo.
Total demand: PSP header + code + stack = 0x0100 + 0xFE00 + 0x0200 = 0x10100 bytes.
Yeh step kyun? Ek single real-mode segment offsets 0x0000–0xFFFF address kar sakta hai, yaani 0x10000 = 65536 bytes total. Demand ko us budget se compare karo.
Compare: 0x10100 > 0x10000 , toh yeh 0x100 = 256 bytes overflow karta hai . Yeh fit nahi hoga.
Yeh step kyun? Offset field sirf 16 bits hai; 0xFFFF ke baad kuch bhi is CS se segment register change kiye bina reach nahi ho sakta.
Segment base (context ke liye): 0x0800 ≪ 4 = 0x08000 , toh segment physical 0x08000–0x17FFF span karta hai; uski last addressable byte 0x17FFF hai.
Yeh step kyun? Answer ko real physical address ke roop mein report karne ke liye segment ki window memory mein anchor karni padti hai: base = CS× 16 , aur highest reachable byte hai base + largest offset (0xFFFF). Yeh "it overflows" ko ek concrete address mein badalta hai jo loader care karta.
Answer: fit NAHI hota — 256 bytes zyada; segment 0x08000–0x17FFF cover karta hai.
Verify: last byte = base + max offset = 0x08000 + 0xFFFF = 0x17FFF ✓, aur 0x10100 − 0x10000 = 0x100 = 256 ✓. Yeh overflow exactly wajah hai kyun bade programs .EXE format use karte the multiple segments ke saath — dekho Memory Addressing Modes .
Definition ModR/M (ek one-byte encoding field)
Zyaadatar x86 instructions jo operands touch karti hain unme ek ModR/M byte hota hai — ek single byte jo naam leta hai kaun sa register aur/ya memory operand opcode act karta hai, aur addressing mode choose karta hai. Yeh instruction ki apni bytes ka hissa hai. Kuch short forms (jaise neeche use hua accumulator-with-displacement MOV) ise skip karte hain. Full field layout ke liye dekho Memory Addressing Modes ; in bytes ke decode ke baad kya bante hain yeh dekhne ke liye dekho Micro-operations (µops) .
Worked example Ex 8 (Cell H) — do-part gotcha
(a) Ek instruction mov eax, [0x11223344] (32-bit displacement, no ModR/M byte, real 5-byte form) CS:IP = 0x0000:0x7FFE par baithi hai. Yahan IP instruction pointer hai — code segment ke andar next instruction run hone wale ka offset. Jab yeh mov execute hoti hai, IP age badh jaata hai. Pehle byte of next instruction ka physical address do. (b) Kya wahi mov legally mov rax, 0x1122334455667788 ho sakta hai? Parent note se 15-byte length cap ke baare mein reason karo.
Forecast: dhyan do offset almost 0xFFFF hit kar raha hai.
(a) Is MOV ki length: opcode 0xA1 (1) + 32-bit displacement (4) = 5 bytes.
Yeh step kyun? Constant 0x11223344 instruction ke andar 4-byte displacement ke roop mein baked hai — bada constant ⇒ lambi instruction (variable length ki root cause).
Next IP (offset): 0x7FFE + 5 = 0x8003 .
Yeh step kyun? IP instruction ki byte length se aage move karta hai. Koi wrap nahi: 0x8003 < 0xFFFF.
Next physical address: 0x0000 ≪ 4 + 0x8003 = 0x08003 .
Yeh step kyun? Standard CS×16+offset with CS = 0.
(b) 64-bit-immediate MOV ki length: REX.W prefix (1) + opcode (1) + 8-byte immediate (8) = 10 bytes.
Yeh step kyun? 10 ≤ 15 , hard cap, toh yeh legal hai — lekin note karo yeh 8086-era 2-byte register move se paanch guna lamba hai, dikhata hai ki immediates length kaise inflate karte hain.
Answers: (a) next byte physical 0x08003 par; (b) haan — 10 bytes ≤ 15-byte cap.
Verify: (a) 0x7FFE + 5 = 0x8003 aur CS 0 ke saath 0x08003 ✓; (b) 1 + 1 + 8 = 10 aur 10 ≤ 15 ✓ (contrast karo RISC vs CISC se, jahan har instruction fixed 4 bytes hai).
Recall Cover-the-matrix self-test
(Cell C) 0x30A0:0x0008 ko alias karne wala ek doosra seg:off pair do.
(Cell D) 0xFFFF:0x0011 20-bit bus par kya wrap karta hai?
(Cell F) RAX = 0xAAAAAAAAAAAAAAAA; mov eax, 1 ke baad, phir mov ah, 2, phir mov al, 3, RAX kya hai?
(Cell G) Ek real-mode segment total kitne bytes address kar sakta hai?
Recall Answers
e.g. segment 0x30A0 - 1 = 0x309F, offset 0x0008 + 0x10 = 0x0018 → 0x309F:0x0018 (dono 0x309A8 dete hain).
0xFFFF0 + 0x11 = 0x100001 → wraps to 0x00001.
mov eax, 1 zero-extends → 0x0000000000000001; mov ah, 2 byte 1 merge karta hai → 0x0000000000000201; mov al, 3 byte 0 merge karta hai → 0x0000000000000203.
0x10000 = 65536 bytes.
Cross-links: Instruction Set Architecture (ISA) · Registers and the Register File · Fetch-Decode-Execute Cycle · ARM Architecture · parent x86 overview .