Advertisement
Guest User

bound.asm

a guest
Aug 19th, 2017
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ; Calling INT 21 from typable code
  3. ; (inspired by https://www.cs.cmu.edu/~tom7/abc)
  4. ;
  5. ; The BOUND instruction is very rarely useful, both
  6. ; because it didn't exist in the original 8086 at all,
  7. ; and also it is not terribly efficient either. It
  8. ; compares a register against a structure containing
  9. ; (signed!) lower and upper bounds, and causes an
  10. ; exception interrupt if the value is outside.
  11. ;
  12. ; The return address will be to the same instruction,
  13. ; which would normally loop endlessly. But since the
  14. ; interrupt is *conditional*, we can avoid it by making
  15. ; sure either the value we are testing or the bounds
  16. ; are changed after return.
  17. ;
  18. ; The trick is to put the bounds on the stack, and then
  19. ; - immediately before executing BOUND - restore SP so that
  20. ; they will be overwritten in a semi-predictable way.
  21. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  22.  
  23.     org 0100h
  24.  
  25. ;;; Copy INT 21 vector to INT 05 (BOUND)
  26. ;;; !! this assumes GS=0000 as it is immediately after reset
  27. ;;;    on actual machine, could have been modified by BIOS, EMM386 etc.
  28.  
  29.     and ax, 2020h
  30.     and ax, 4040h
  31.     xor al, 60h
  32.     push ax
  33.     pop si          ; SI=0060
  34.     xor al, 60h     ; clear AX
  35.     push ax         ; save it
  36.     dec ax
  37.     sub al, 20h
  38.     push ax
  39.     pop di          ; DI=-0021
  40.     pop ax          ; restore zero in AX
  41.     and [gs:di+35h], ax ; clear [0014]
  42.     and [gs:di+37h], ax ; clear [0016]
  43.     push ax
  44.     xor ax, [gs:si+24h] ; load [0084]
  45.     xor [gs:di+35h], ax ; store [0014]
  46.     pop ax
  47.     push ax
  48.     xor ax, [gs:si+26h] ; load [0086]
  49.     xor [gs:di+37h], ax ; store [0016]
  50.     pop ax
  51.  
  52. ;;; Now set up bounds record on stack, which will get overwritten
  53. ;;; by flags/CS/IP on interrupt. Min/max is set to zero, so any
  54. ;;; positive number causes INT 05. On return, minimum bound is
  55. ;;; saved IP and maximum=saved CS, so this must be near the start
  56. ;;; of the code segment.
  57.  
  58. ;;; In an EXE file, we could guarantee IP <= CS by placing
  59. ;;; the code below 0060; CS can never be that low because
  60. ;;; of the interrupt table and BIOS data area. But DOS should
  61. ;;; normally take up enough space in low memory that this isn't
  62. ;;; really necessary.
  63.  
  64.     push sp
  65.     pop si          ; save stack pointer in SI
  66.     push ax         ; reserve space for flags (don't care)
  67.     push ax         ; upper bound, overwritten with CS
  68.     push ax         ; lower bound, overwritten with IP
  69.     push sp
  70.     pop di          ; DI=>bounds
  71.     push si         ; will be popped into SP just before BOUND
  72.  
  73. ;;; Load SI with known IP of bound instruction
  74. ;;; set up other regs for printing string
  75.  
  76.     xor ax, 216bh
  77.     xor ax, 2020h
  78.     push ax
  79.     pop si          ; SI=014B
  80.     xor ax, 2820h
  81.     xor ax, 2020h       ; AH=09
  82.     push si
  83.     pop dx
  84.     inc dx
  85.     inc dx
  86.     inc dx          ; DX=014E
  87.  
  88. ;;; Restore stack pointer and execute BOUND
  89. ;;; !! race condition if hardware int occurs immediately after pop
  90. ;;;    to be really sure DOS did its thing, we would have to check
  91. ;;;    for a known return value from the function we are calling...
  92.  
  93.     pop sp
  94.     bound si, [di]
  95.  
  96. ;;; Proof of concept done, now cheating is allowed :)
  97.  
  98.     ret
  99.     db "Hello world!",13,10,36
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement