-1

我是汇编程序的小菜鸟,但是我有一点需要大量反思的作业,我必须修改中断子程序,例如当我调用int21h时,我想显示一条消息HELLO WORD,或者当我想除以0,例如我想显示数字5,所以我知道向量中断的所有段是CS:0000,偏移量是0084(对于int21h),当我想调用int21时是否请求,我想要我的微处理器执行另一个可以在 [0700:1200] 中找到的程序,所以我需要更改内容 0000:0084 ( int 21 的地址);我试过一个想法是 mov [0000],0700 mov [0084],1200

但不幸的是不起作用有我的例子

org 100 
mov dx,000
push ds
mov ds,dx
lea bx,qwert  
mov [0084h],1500h
int 21h hlt 
org 1200
jmp qwert
pa equ 20h
pb equ 22h`
pc equ 24h
regcontrol equ 26h
tab db 3fh,06h,5bh,4FH,66H,6Dh,7dh,07h,7fh,6fh
com equ 90h
qwert:        
 mov ax,com
out regcontrol,ax 
debut:
mov al,0FFH
OUT pc,al
  call tempo
  mov al,00h
  out pc,al
  call tempo
  jmp debut 
ret   

 proc tempo
    mov cx,7fffh
   ici:nop
   nop
   nop
   nop
   nop
   nop
     loop ici 
       ret
     endp

所以,我想要的是什么时候执行int21h,我想这个中断直接去执行程序qwerty,程序qwerty创建于0700:0112(我使用emu 8086),但是int 21h直接进入f400:1500 .

我希望你能理解我,并为我糟糕的英语感到抱歉

4

1 回答 1

2

现在我完全阅读了你的问题......有些事情可能值得回答:

所以我知道向量中断的所有段是 CS:0000 并且偏移量是 0084(对于 int21h)

这混淆了几件事。cs是寄存器,连同它一起存储要执行的指令的ip地址( )。cs:ip虽然您一开始在自己的代码中,但cs = 0700h, 直到您通过 . 跳转到其他地方int 21h

中断向量表(包含中断处理程序的地址)位于内存中,从0000:0000地址开始。

表中的每个条目都包含四个字节,因此偏移量为21h21h*4 = 84h不是 84,而是 84h == 132)。

单项的这四个字节是segment:offset例程的地址,偏移量部分存储为第一个字,段部分是第二个字(at 0:86h)。您的原始代码确实只设置了偏移部分,但没有设置段,这就是它跳转到的原因F400h:1500h,您没有更改旧F400h的原始 DOS 处理程序。

...所以我需要更改内容 0000:0084 ( int 21 的地址);

是的(虽然你想修改21h,所以地址是84h,但你的句子即使对于十进制值也是如此,如果你想改变int 15h,那么地址0000:0084是正确的)。

我试过一个想法是 mov [0000],0700 mov [0084],1200

不。mov [0000],0700不会修改内存ds:0000。重新阅读一些解释什么segment:x86 16b实模式下的偏移量(物理地址=段* 16 +偏移量)。

因此,当int 21h向量位于(所有数字将从此处开始为六进制)0000:0084时,这意味着它位于物理内存地址0000 * 10 + 0084 = 00084。地址0000:0000是 的向量int 0

如果您看到0000:0084,那不是两个偏移量(修改 [0000] 和 [0084]),而是指向值的第一个字节的单个内存地址。存储 32 位segment:offset值意味着将 16b 偏移部分写入 +0 和 +1 字节,将 16b 段值写入 +2 和 +3 字节。

因此,如果旧的int 21h处理程序是 例如F400:DEAD,那么地址处的内存0000:0084包含四个字节:AD DE 00 F4。在调试器中使用内存视图查看中断表及其初始内容。您来自问题的原始代码确实将其修改为00 15 00 F4,然后int 21h跳转到该地址(F400:1500)。

于 2017-03-23T03:54:34.707 回答