5.1.2 · D3 · Hardware › Instruction Set Architecture (ISA) › Instruction formats and encoding
Intuition Ye page kis kaam ki hai
Parent note Instruction formats and encoding ne tumhe 32 bits mein ek instruction pack karne ke rules sikhaye. Ye page unhi rules ki itni drilling karta hai ki koi bhi scenario tumhe surprise na kare : positive aur negative immediates, bits ka split karna, sign-extension, zero aur maximum values, aur woh trap questions jo exam mein baar baar aate hain. Har worked example raw bits se banaya gaya hai — kuch bhi assume nahi kiya gaya.
Shuru karne se pehle, teen words ko plain language mein dobara anchor karte hain jis par puri page tiki hai:
Definition Teen words jo hum baar baar use karenge
Ek bit ek single 0 ya 1 hota hai. Ek light switch socho: off = 0, on = 1.
Ek field neighbouring bits ka ek fixed group hota hai jiska ek kaam hota hai. Ek aisi row of switches socho jiske upar ek label laga ho ("ye row = destination register").
Encoding = tumhare paas real numbers hain (register 5, immediate −8) aur tum switches fill in karte ho. Decoding = CPU switches ko wapas meaning mein padhta hai.
Neeche har number binary (base 2) mein likha hai: right-to-left padhne par columns ki value 1 , 2 , 4 , 8 , 16 , … (powers of two) hoti hai. Toh 00101 ka matlab hai 4 + 1 = 5 .
Definition Bracket notation
imm[a:b] — use karne se pehle define karo
Jab ek immediate split hota hai, hume yeh name karna padta hai ki uske kaun se bits kahan rehte hain. Notation ==imm [ a : b ] ka matlab hai "immediate value ke bits a se lekar b tak, right se count karte hue (bit 0 ones column hai)."== Toh imm [ 4 : 0 ] lowest five bits hain, aur imm [ 11 : 5 ] unke upar wale saat bits hain. Ek single bit imm [ 7 ] likha jaata hai (sirf bit 7). Immediate ko switches ke ek numbered ruler ki tarah socho; imm[a:b] us ruler ke ek labelled hisse ko fence off karta hai.
Do prerequisites jin par hum depend karte hain aur inhe kahan revise karein: Registers and the Register File (kyun ek register number sirf ek chota integer hai) aur Two's Complement and Sign Extension (bits mein negative numbers kaise rehte hain).
Har encoding question jo tum kabhi bhi dekhoge woh in cells mein se ek hogi. Neeche ke worked examples us cell ke saath tagged hain jo woh cover karte hain, aur milke woh saari cells hit karte hain.
#
Cell (case class)
Tricky kyun hai
Example
A
Simple positive R-type
bas registers pack karo
Ex 1
B
Positive immediate (I-type)
immediate ek block mein hota hai
Ex 2
C
Negative immediate
top bit = sign, sign-extend karna zaroori
Ex 3
D
Zero / degenerate input
register 0, immediate 0
Ex 4
E
Maximum / limiting value
ek field mein sabse bada immediate
Ex 5
F
Split immediate (S-type)
bits do holes mein bikhar jaate hain
Ex 6
G
Reordered + scaled (B-type)
immediate 2 bytes ke units mein
Ex 7
H
Decode direction (bits → meaning)
poora process reverse karo
Ex 8
I
Field-width word problem
requirements se bit counts choose karo
Ex 9
J
Exam twist (opcode-budget trap)
zyada opcode ≠ zyada room
Ex 10
R-type field order jo hum baar baar use karenge (parent note se) woh "phone number" 7-5-5-3-5-7 hai — neeche diye figure mein picture dekho; math line sirf unhi fences ko naam deti hai:
7 f u n c t 7 5 r s 2 5 r s 1 3 f u n c t 3 5 r d 7 o p co d e
Worked example Example 1 —
add x5, x6, x7 encode karo
Pehle forecast karo: add ka opcode hai 0110011, funct3 = 000, funct7 = 0000000. Aage padhne se pehle guess karo: registers 5, 6, 7 ke 5-bit patterns kya honge, aur woh left-to-right order mein kahan baithenge?
Step 1 — har register number ko 5 bits mein badlo.
5 = 4 + 1 → 00101 , 6 = 4 + 2 → 00110 , 7 = 4 + 2 + 1 → 00111 .
Yeh step kyun? Har register field exactly 5 bits wide hai (32 registers ke liye ⌈ log 2 32 ⌉ = 5 bits chahiye), toh hume har number ko 5 columns mein likhna hoga, leading zeros se pad karke.
Step 2 — identify karo kaun sa register kaun sa hai. add rd, rs1, rs2 mein: destination rd = x5, pehla source rs1 = x6, doosra source rs2 = x7.
Yeh step kyun? Assembly mein destination pehle aata hai, lekin bits mein rs2 bilkul left mein hota hai aur rd opcode ke paas — inhe mix karna #1 error hai. Upar wala figure dekho: destination opcode ke paas hota hai (green), sources aur left mein (blue).
Step 3 — har field ko uske 7-5-5-3-5-7 slot mein daalo.
f u n c t 7 0000000 r s 2 = 7 00111 r s 1 = 6 00110 f u n c t 3 000 r d = 5 00101 o p co d e 0110011
Yeh step kyun? Instruction Decode Stage hamesha lowest 7 bits ko opcode ki tarah padhta hai, toh hum fields exactly wahin rakhte hain jahan decode dekhta hai.
Verify: bits count karo: 7 + 5 + 5 + 3 + 5 + 7 = 32 . ✓ Ek 32-bit binary ke roop mein poora word hex mein 0x007302B3 ke barabar hai — VERIFY mein check kiya.
Intuition I-type mein kya badlata hai
Ek immediate ek aisa number hai jo directly instruction mein baked hota hai (Latin "immediate" se = bilkul yahan, koi lookup nahi). I-type ke liye hume rs2 ya funct7 ki zaroorat nahi; hum un 12 bits ko ek 12-bit immediate field mein chipka dete hain. Bracket notation ko use karte hue jo humne abhi define ki, saare barah bits imm [ 11 : 0 ] ek saath rehte hain:
12 imm [ 11 : 0 ] 5 r s 1 3 f u n c t 3 5 r d 7 o p co d e
Worked example Example 2 —
addi x1, x2, 100 encode karo
Forecast: 12 bits mein 100 — guess karo iske kitne leading zeros chahiye.
Step 1 — 100 ko binary mein likho. 100 = 64 + 32 + 4 = 1100100 (7 bits).
Kyun? Raw value chahiye pehle, tab hum jaanenge ki 12-bit field ke liye kitna padding lagega.
Step 2 — 12 bits tak pad karo. 100 = 000001100100 .
Kyun? Immediate field 12 columns wide hai; positive numbers leading zeros se pad hote hain. Top bit 0 hai, jo (Ex 3 preview karte hue) "positive" ka matlab hai.
Step 3 — fields place karo. addi opcode = 0010011, funct3 = 000, rs1 = x2 = 00010, rd = x1 = 00001.
imm = 100 000001100100 r s 1 00010 f u n c t 3 000 r d 00001 o p co d e 0010011
Verify: 12 + 5 + 3 + 5 + 7 = 32 ✓. Immediate wapas decode karo: 00000110010 0 2 = 100 ✓ (VERIFY mein check kiya).
Intuition Negative numbers ko special rule kyun chahiye
Ek 12-bit field mein sirf 12 switches hain, lekin Instruction Decode Stage ko use 32 bits tak widen karna padta hai ALU ke add karne se pehle. Agar hum − 8 ko sirf zeros se pad karke widen karte, toh top ek bahut bada positive number lagta. Sign extension top bit ko bahar copy karta hai, toh negative negative hi rehta hai. Yeh exactly Two's Complement and Sign Extension hai.
Worked example Example 3 —
addi x1, x2, -8 encode karo, phir sign-extend karo
Forecast: 12-bit two's complement mein, kya − 8 1 se start hoga ya 0 se? Guess karo 32-bit widen value kaisi dikhegi.
Step 1 — − 8 ko 12-bit two's complement mein dhundho. + 8 = 000000001000 lo, har bit flip karo → 111111110111 , 1 add karo → 111111111000 .
Kyun? Two's complement "invert and add one" ke roop mein define hoti hai; yahi woh pattern deta hai jiska value − 8 hai.
Step 2 — sign bit padho. Bit 11 (leftmost) 1 hai ⇒ negative. ✓ Forecast confirm.
Kyun? Two's complement mein top bit akela sign batata hai — 1 matlab negative.
Step 3 — 32 bits tak sign-extend karo. Top bit (1) ko extra 20 bits mein copy karo:
20 copied ones 1111 1111 1111 1111 1111 − 8 in 12 bits 1111 1111 1000
Kyun? Sign bit copy karne se value − 8 rehti hai, na ki + 4088 ban jaati. Figure mein top bit ko left ki taraf fan out hote dikhaaya gaya hai.
Verify: 32-bit result ko signed interpret karo: yeh − 8 ke barabar hai. Aur + 4088 galat zero-extended answer hoga — dono VERIFY mein check kiye.
Worked example Example 4 —
add x0, x0, x0 encode karo
Forecast: register 0 RISC-V mein special hai (yeh hard-wired hai hamesha 0 read karne ke liye). Guess karo jab sab kuch zero ho toh poora instruction word kaisa dikhega.
Step 1 — register 0 encode karo. 0 = 00000 (paanch zeros). Teeno register fields 00000 hain.
Kyun? Zero ek valid register index hai; bas ittifaq se yeh all-zeros hai. Degenerate inputs fir bhi normal rule follow karte hain.
Step 2 — assemble karo. add ka opcode 0110011, funct3 000, funct7 0000000 rehta hai:
0000000 00000 00000 000 00000 0110011
Kyun? Layout mein kuch nahi badlata; sirf values zero hain.
Verify: 32-bit integer ke roop mein yeh 0x00000033 hai, all-zero nahi — kyunki opcode bits abhi bhi set hain. Lesson: "zeros par kuch mat karo" instruction all-zero word nahi hoti. VERIFY mein check kiya. (Sacchi all-zero word 0x00000000 RISC-V mein ek illegal instruction hai — yaad rakhne wala ek sundar degenerate edge.)
Worked example Example 5 — I-type mein sabse bada aur sabse chota immediate kya ho sakta hai?
Forecast: ek 12-bit signed field — guess karo do extremes kya hain.
Step 1 — range split karo. 12 bits ke saath, ek bit sign hai, 11 magnitude bits bachte hain.
Kyun? Two's complement mein range asymmetric hoti hai: negatives ko ek extra slot milta hai kyunki 0 non-negative count hota hai.
Step 2 — extremes compute karo.
max = 2 11 − 1 = 2047 , min = − 2 11 = − 2048.
Kyun? Sabse bada positive all-ones-except-sign hai (011 … 1 ); sabse negative sign-bit only hai (100 … 0 ). Positive side par "− 1 " isliye hai kyunki ek pattern zero par kharcha ho gaya.
Step 3 — pattern check karo. 2047 = 011111111111 , − 2048 = 100000000000 .
Yeh step kyun? Hum confirm karte hain ki extremes valid bit-patterns hain aur off by one nahi: 011111111111 mein har magnitude bit set hai aur 0 sign bit hai (sabse bada positive), aur 100000000000 sirf sign bit hai (sabse negative). Actual bits dekhna classic ± 1 range error se bacha ta hai.
Verify: 2 11 − 1 = 2047 aur − 2 11 = − 2048 , aur 100000000000 ko two's complement mein decode karne par − 2048 milta hai — sab VERIFY mein check kiye. Limiting behaviour: addi x1,x2,2048 maango aur assembler reject kar deta hai — yeh fit nahi hota.
Intuition Immediate kyun kaata jaata hai
Store sw x7, 12(x2) ke liye hume abhi bhi rs1 aur rs2 apni usual jagah chahiye taaki register-read wiring kabhi na bade. Yeh ek single 12-bit hole nahi chhodta — toh 12-bit offset do leftover gaps mein split ho jaata hai. Yeh split ek hardware convenience hai, math mein koi badlaav nahi.
7 imm [ 11 : 5 ] 5 r s 2 5 r s 1 3 f u n c t 3 5 imm [ 4 : 0 ] 7 o p co d e
Worked example Example 6 —
sw x7, 12(x2) ka offset encode karo
Forecast: offset 12 hai. Iske bits top-7 aur bottom-5 pieces mein kaise divide honge?
Step 1 — 12 ko 12 bits mein likho. 12 = 8 + 4 = 000000001100 .
Kyun? Kaatne se pehle saare 12 bits chahiye.
Step 2 — imm[11:5] aur imm[4:0] mein kaato.
imm [ 4 : 0 ] = lowest 5 bits = 01100
imm [ 11 : 5 ] = agले 7 bits = 0000000
Kyun? Upar se bracket notation use karte hue: hum same number 12 ko do pieces mein slice karte hain jo alag-alag fields mein rehte hain.
Step 3 — inhe place karo. sw opcode 0100011, funct3 010, rs1 x2 = 00010, rs2 x7 = 00111:
imm [ 11 : 5 ] 0000000 r s 2 00111 r s 1 00010 f u n c t 3 010 imm [ 4 : 0 ] 01100 o p co d e 0100011
Verify: imm [ 11 : 5 ] ∥ imm [ 4 : 0 ] reassemble karo = 0000000 01100 = 12 ✓ (VERIFY mein check kiya). Register fields rs1, rs2 same positions par hain jaise R-type mein — yahi toh poora point hai.
Neeche wala figure dekho. Top row plain 12-bit value 12 dikhata hai; coloured arrows uske do slices ko S-type template mein le jaate hain. Notice karo ki green slice (imm [ 11 : 5 ] ) aur orange slice (imm [ 4 : 0 ] ) non-adjacent holes mein jaate hain, jabki rs1 aur rs2 (blue) exactly wahin rehte hain jahan R-type ne unhe rakha tha — woh unchanged register wiring hi poore split ki wajah hai.
Intuition Branch ke do extra twists
Ek branch offset (beq x1, x2, target) mein S-type split se aage do surprises hain:
Scaled by 2 — instructions 2-byte aligned hote hain, toh offset 2 bytes ke units mein store hota hai; bit 0 hamesha 0 hota hai aur store nahi hota. n store hone ka matlab hai 2 n bytes jump karo.
Reordered — bits permute hote hain taaki sign bit same top position par aaye jaise har doosre format mein, ek sign-extend wire sabhi formats ko serve kare.
Intuition Exact B-type field breakdown (kaun sa bit kahan jaata hai)
Ek branch offset ek 13-bit signed number imm [ 12 : 0 ] hai, lekin kyunki bit 0 hamesha 0 hai (2-byte alignment) sirf 12 bits actually store hote hain. Iska sign bit imm [ 12 ] hai, top bit. RISC-V store hue bits ko aise pack karta hai (S-type ke 5/7-wide holes, reshuffled):
7 imm [ 12 ] ∥ imm [ 10 : 5 ] 5 r s 2 5 r s 1 3 f u n c t 3 5 imm [ 4 : 1 ] ∥ imm [ 11 ] 7 o p co d e
Slice widths: imm [ 12 ] = 1 bit, imm [ 10 : 5 ] = 6 bits (7-bit top hole fill karta hai), imm [ 4 : 1 ] = 4 bits, imm [ 11 ] = 1 bit (5-bit low hole fill karta hai). Bit imm [ 12 ] (sign) ekdum top par hota hai taaki ek sign-extend wire har format ke liye kaam kare.
Worked example Example 7 —
beq x1, x2, +12 ka branch offset encode karo aur distance confirm karo
Forecast: compute karne se pehle guess karo — kya "12 bytes" matlab wala stored value sign bit mein 1 rakhega? Kya branch forward hai ya backward?
Step 1 — byte offset ko 13-bit signed value mein likho. + 12 = 0 0000 0000 1100 as imm [ 12 : 0 ] (terah bits, bit 0 right par).
Kyun? Branch offsets 13-bit signed byte distances hain; bits mein se slices nikalne se pehle har bit chahiye.
Step 2 — hamesha-zero bottom bit padho. imm [ 0 ] = 0 . ✓
Kyun? Instructions 2-byte aligned hain, toh byte offset hamesha even hota hai — bit 0 guaranteed 0 hai aur isliye store nahi hota (yahi "scaled by 2" trick hai). Stored halfword-count hai 12/2 = 6 .
Step 3 — har named slice nikalo. imm [ 12 : 0 ] = 0 0000 0000 1100 se:
imm [ 12 ] (sign) = 0
imm [ 11 ] = 0
imm [ 10 : 5 ] = 000000
imm [ 4 : 1 ] = 0110 (bits 4,3,2,1 = 0,1,1,0)
Kyun? Yeh exactly woh chaar slices hain jo B-type template maangta hai; hum 13-bit ruler ko upar breakdown callout mein named pieces mein kaatate hain.
Step 4 — slices ko 7-5-5-3-5-7 template mein place karo. beq opcode 1100011, funct3 000, rs1 x1 = 00001, rs2 x2 = 00010:
imm [ 12 ] ∥ imm [ 10 : 5 ] 0 000000 r s 2 00010 r s 1 00001 f u n c t 3 000 imm [ 4 : 1 ] ∥ imm [ 11 ] 0110 0 o p co d e 1100011
Kyun? Har slice apne assigned hole mein jaati hai taaki sign bit imm [ 12 ] ekdum top position par aaye, jo har doosre format ke sign bit ke saath shared hai.
Verify: stored halfword count 6 hai, toh effective jump 6 × 2 = 12 bytes forward hai; sign bit imm [ 12 ] = 0 confirm karta hai forward . Charon slices ko wapas imm [ 12 : 0 ] mein reassemble karne par 12 milta hai — sab VERIFY mein check kiye. Yahi parent-note ki galti hai: raw field ≠ effective value. Pucho "kya yeh scaled hai ya sign-extended?" — B-type ke liye, dono .
Worked example Example 8 — 32-bit word
0x00C58533 decode karo
Forecast: ab hum ulta ja rahe hain. Guess karo: hum pehle kaun sa field padhte hain?
Step 1 — hex ko 32 bits mein likho. 0x00C58533 = 0000 0000 1100 0101 1000 0101 0011 0011.
Kyun? Har hex digit 4 bits hai; individual fields dekhne ke liye expand karte hain.
Step 2 — lowest 7 bits (opcode) peelo. Lowest 7 = 0110011 → R-type add class.
Kyun? Decode hamesha opcode pehle padhta hai, low end se — yeh batata hai ki baki kaunsa format follow karta hai.
Step 3 — baaki fields ko 7-5-5-3-5-7 se slice karo. Opcode se upar padhte hue:
rd (agले 5) = 01010 = x10
funct3 (3) = 000
rs1 (5) = 01011 = x11
rs2 (5) = 01100 = x12
funct7 (7) = 0000000
Kyun? Hum packing reverse karte hain: same fences, values andar dalne ki jagah bahar nikalte hain.
Verify: instruction hai add x10, x11, x12. Un fields ko wapas encode karne par 0x00C58533 milta hai — VERIFY mein check kiya.
Worked example Example 9 — Ek tiny ISA design karo
Problem: Ek toy CPU mein 16 registers hain aur 40 distinct operations chahiye. Har instruction [opcode][rd][rs1] hai (do registers). Minimum instruction width kya hai?
Forecast: guess karo ki yeh ek byte (8 bits) mein fit ho jaata hai ya nahi.
Step 1 — opcode bits. ⌈ log 2 40 ⌉ : 2 5 = 32 < 40 , 2 6 = 64 ≥ 40 → 6 bits .
Kyun? b bits ka ek field 2 b patterns encode karta hai; hume kam se kam 40 chahiye, toh 6.
Step 2 — register bits. 16 registers → ⌈ log 2 16 ⌉ = 4 bits har ek ke liye, aur do register fields hain (rd aur rs1), toh 4 + 4 = 8 bits.
Kyun? 2 4 = 16 exactly 16 registers cover karta hai, aur problem mein do register operands bataaye hain.
Step 3 — total karo aur round up karo. 6 + 4 + 4 = 14 bits. Real hardware whole bytes fetch karta hai, toh byte boundary tak round up karo → 16 bits (2 bytes).
Kyun? 14-bit word 2 bits waste karta hai lekin clean byte-aligned fetching ke liye 16 tak padded hota hai. Yeh miniature mein RISC vs CISC fixed-width philosophy hai.
Verify: ⌈ log 2 40 ⌉ = 6 , ⌈ log 2 16 ⌉ = 4 , sum = 14 , 16 tak rounded — sab VERIFY mein check kiye. Toh forecast ka jawab hai nahi , ek byte kaafi nahi hai.
Worked example Example 10 — Tempting wrong answer
Problem: "Ek student 32-bit fixed-width R-type mein primary opcode ko 7 se 12 bits tak widen karta hai zyada operations support karne ke liye, teeno 5-bit registers, ek 3-bit funct3 aur 7-bit funct7 rakhte hue. Kya yeh fit hota hai? Kya toota?"
Forecast: add karne se pehle guess karo haan ya nahi.
Step 1 — demanded bits sum karo. 12 ( opcode ) + 5 + 5 + 5 ( regs ) + 3 ( f u n c t 3 ) + 7 ( f u n c t 7 ) = 37 bits.
Kyun? Word ek fixed 32-bit budget hai; opcode mein add kiya gaya har bit kahin aur se chura liya gaya hai. Hum total karte hain ki design kya maangta hai aur compare karte hain kya hamare paas hai se.
Step 2 — budget se compare karo. 37 > 32 . Yeh fit nahi hota. Kuch drop karna padega — shayad funct7, add aur sub ke beech distinguish karne ki ability kho kar.
Kyun? Yeh parent-note ki galti steel-manned hai: zyada opcode bits ≠ zyada usable instructions agar woh required fields ko crowd out kar dein.
Step 3 — sahi fix. 7-bit opcode rakho aur funct3/funct7 sub-fields se operations expand karo, exactly jaisa real RISC-V karta hai — koi budget overflow nahi.
Kyun? Sub-fields operation count ko existing opcode class ke andar multiply karte hain scarce primary-opcode bits kharche bina.
Verify: 12 + 5 + 5 + 5 + 3 + 7 = 37 > 32 ✓ (VERIFY). Trap answer "haan fit hota hai" provably galat hai.
Recall Poore matrix par quick self-test
Kaun si cell mein stored value ko use karne se pehle 2 se multiply kiya jaata hai? ::: Cell G (B-type branch, 2 bytes se scaled).
S-type apna immediate split kyun karta hai? ::: Taaki rs1 aur rs2 apni normal positions par rahein aur register-read wiring kabhi na bade.
12-bit signed immediate ki sabse badi value? ::: + 2047 ; sabse choti − 2048 hai.
B-type immediate ka sign bit kaun sa hai? ::: imm [ 12 ] , top bit, word ke bilkul top par place hota hai taaki ek sign-extend wire sabhi formats ko serve kare.
add x0,x0,x0 encode karo — kya word all zeros hai? ::: Nahi — opcode bits 0110011 abhi bhi set hain (0x00000033).
Decoder pehle kaun sa field padhta hai? ::: Opcode, lowest 7 bits mein.
Mnemonic Kisi bhi encoding question ka answer dene se pehle scenario checklist
"S-S-S-P" — kya yeh S igned hai? S plit hai? S caled hai? Aur kya yeh P udget (budget) mein fit hota hai? Yeh chaar pucho aur koi bhi exam twist tumhe ambush nahi kar sakta.
Yeh bhi dekho: Addressing Modes (immediate kaise memory address banta hai) aur Pipelining (kyun fixed-width fields decode ko itna fast banate hain ki overlap ho sake).