# modrm19.s -- derive the complete 16-bit ModR/M effective-address table by # EXECUTION, not from memory. 24 cases: 8 r/m values x 3 mod values. # # For each case: clear 0x0000..0x4FFF, store 0xBEEF through the encoding under # test, then scan for the word and emit its offset as 2 raw bytes. # BX=0x1000 DI=0x2000 SI=0x0030 BP=0x0040, so every candidate is distinct. # # mod=00 : no displacement follows # mod=01 : disp8 = 0x44 # mod=10 : disp16 = 0x1234 # # The three "mod=11" cases are register-to-register and are not addressed here. # Output: 24 groups of "lo hi 0x20", then 0x0A 0x0A. .code16 .text .globl _start _start: cli xorw %ax, %ax movw %ax, %es movw $0x1000, %bx movw $0x2000, %di movw $0x0030, %si movw $0x0040, %bp # ---- mod = 00, r/m = 000..111 ------------------------------- call clr movw $0xBEEF, %ax .byte 0x26, 0x89, 0x00 # 00 000 call rep_ call clr movw $0xBEEF, %ax .byte 0x26, 0x89, 0x01 # 00 001 call rep_ call clr movw $0xBEEF, %ax .byte 0x26, 0x89, 0x02 # 00 010 call rep_ call clr movw $0xBEEF, %ax .byte 0x26, 0x89, 0x03 # 00 011 call rep_ call clr movw $0xBEEF, %ax .byte 0x26, 0x89, 0x04 # 00 100 call rep_ call clr movw $0xBEEF, %ax .byte 0x26, 0x89, 0x05 # 00 101 call rep_ call clr movw $0xBEEF, %ax .byte 0x26, 0x89, 0x06, 0x34, 0x12 # 00 110 direct call rep_ call clr movw $0xBEEF, %ax .byte 0x26, 0x89, 0x07 # 00 111 call rep_ # ---- mod = 01, disp8 = 0x44 -------------------------------- call clr movw $0xBEEF, %ax .byte 0x26, 0x89, 0x40, 0x44 # 01 000 call rep_ call clr movw $0xBEEF, %ax .byte 0x26, 0x89, 0x41, 0x44 # 01 001 call rep_ call clr movw $0xBEEF, %ax .byte 0x26, 0x89, 0x42, 0x44 # 01 010 call rep_ call clr movw $0xBEEF, %ax .byte 0x26, 0x89, 0x43, 0x44 # 01 011 call rep_ call clr movw $0xBEEF, %ax .byte 0x26, 0x89, 0x44, 0x44 # 01 100 call rep_ call clr movw $0xBEEF, %ax .byte 0x26, 0x89, 0x45, 0x44 # 01 101 call rep_ call clr movw $0xBEEF, %ax .byte 0x26, 0x89, 0x46, 0x44 # 01 110 call rep_ call clr movw $0xBEEF, %ax .byte 0x26, 0x89, 0x47, 0x44 # 01 111 call rep_ # ---- mod = 10, disp16 = 0x1234 ------------------------------ call clr movw $0xBEEF, %ax .byte 0x26, 0x89, 0x80, 0x34, 0x12 # 10 000 call rep_ call clr movw $0xBEEF, %ax .byte 0x26, 0x89, 0x81, 0x34, 0x12 # 10 001 call rep_ call clr movw $0xBEEF, %ax .byte 0x26, 0x89, 0x82, 0x34, 0x12 # 10 010 call rep_ call clr movw $0xBEEF, %ax .byte 0x26, 0x89, 0x83, 0x34, 0x12 # 10 011 call rep_ call clr movw $0xBEEF, %ax .byte 0x26, 0x89, 0x84, 0x34, 0x12 # 10 100 call rep_ call clr movw $0xBEEF, %ax .byte 0x26, 0x89, 0x85, 0x34, 0x12 # 10 101 call rep_ call clr movw $0xBEEF, %ax .byte 0x26, 0x89, 0x86, 0x34, 0x12 # 10 110 call rep_ call clr movw $0xBEEF, %ax .byte 0x26, 0x89, 0x87, 0x34, 0x12 # 10 111 call rep_ movw $0x3F8, %dx movb $10, %al outb %al, %dx hlt # clr -- clear 0000:0000..0000:4FFF clr: pushw %di pushw %cx pushw %ax xorw %ax, %ax movw $0x0000, %di movw $0x2800, %cx rep stosw popw %ax popw %cx popw %di ret # rep_ -- emit the address of the word just stored rep_: pushw %ax pushw %bx pushw %cx pushw %dx pushw %si pushw %di xorw %si, %si scan: cmpw $0x3600, %si jae none movw %es:(%si), %dx cmpw $0xBEEF, %dx je found incw %si jmp scan found: movw %si, %ax call putb movb %ah, %al call putb jmp done none: movw $0xFF, %ax call putb movw $0xFF, %ax call putb done: movw $0x3F8, %dx movb $' ', %al outb %al, %dx popw %di popw %si popw %dx popw %cx popw %bx popw %ax ret putb: pushw %dx movw $0x3F8, %dx outb %al, %dx popw %dx ret