嗨我已经重定向分频溢出中断指向我自定义创建的中断,在屏幕上打印'你好我在这里',而不是打印奇怪的ascii字符。有人可以告诉我为什么吗?这是代码
[ORG 100h]
jmp start
message: dw 'hello man here i am'
prntstr: push ax
push bx
push cx
push dx
push si
push di
push bp
push ds
push es
push cs
pop ds
mov ah, 0x13
mov al, 1
mov bh, 0
mov bl, 7
mov dx,0x0a03
mov cx,11
push cs
push es
mov bp,message
int 0x10
pop es
pop ds
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
tsr: mov ah, 0
int 0x16
call prntstr
iret
;mov ah,4ch
;mov al, 6
;int 0x21
;iret
divs: mov ax,0x8569
mov dl,2
div dl
ret
start: xor ax,ax
mov es,ax
mov word[es:0*4], tsr
mov [es:0*4+2],cs
call divs
mov ax,0x4c00
int 0x21
我不明白的代码是我在es:0 * 4设置偏移量的地方 - 我认为00是除法溢出中断的位置?什么是0 * 4 for coz任何乘以零意味着相同,那为什么4?提前谢谢
答案 0 :(得分:1)
至于你奇怪的角色问题,我想:
push cs
push es
应该是:
push cs
pop es
否则:
es
段注册表未设置为es:bp
以正确指向该消息。它将打印段message
中偏移es
处的任何内容,当您的中断触发时,而不是在您的实际消息所在的代码段中。对于0*4
问题,我不确定。我做了x86已经有一段时间,但我知道你可以扩展间接寻址模式,例如:
mov eax, dwarray[edx*4]
确保访问正确的内存位置。在添加到edx
基地址之前,这会将dwarray
缩放到正确的值。
我认为不需要立即补偿,所以我怀疑只需用相关代替0
就可以更改任何中断的样板代码中断号码。
另外,您可能不想要更改中断向量而不确保在此过程中禁用中断。如果中断在之后触发你已经写了tsr
的偏移量,但是之前的你已经写了段,那么结果将不会很好。
答案 1 :(得分:0)
您的代码中存在多个问题。见评论:
[ORG 100h]
jmp start
message: db 'hello man here i am' ; chars are 8-bit, hence db, not dw
msglen equ $ - message ; calculate message length
prntstr: push ax
push bx
push cx
push dx
push si
push di
push bp
push ds
push es
;push cs ; not really needed here
;pop ds
mov ah, 0x13
mov al, 1
mov bh, 0
mov bl, 7
mov dx,0x0a03
mov cx,msglen ; use proper message length
push cs
pop es ; not "push es" - copy'n'paste bug !!!
mov bp,message
int 0x10
pop es
pop ds
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
tsr:
call prntstr
; skip DIV (by advancing IP) to avoid infinite loop on DIV
push bp
mov bp, sp
add word [bp+1*2], divend-divstart; IP (location of divstart) on the stack
pop bp
push ax ; save AX because int 0x16 will change it
mov ah, 0
int 0x16
pop ax ; restore AX
iret
divs: mov ax,0x8569
mov dl,2
divstart:
div dl
divend:
ret
start:
mov ax, 3
int 0x10 ; clear screen by setting mode 3
xor ax,ax
mov es,ax
cli ; update ISR address w/ ints disabled
push word[es:0*4+2] ; preserve ISR address
push word[es:0*4]
mov word[es:0*4], tsr
mov [es:0*4+2],cs
sti
call divs
cli ; update ISR address w/ ints disabled
pop word[es:0*4] ; restore ISR address
pop word[es:0*4+2]
sti
mov ax,0x4c00
int 0x21
4是一个远指针大小(偏移量为2个字节,段选择器为2个字节)。因此,对于int 0
,中断向量表中的地址将为0*4
,对于int 1
,它将为1*4
,对于int n
,它将为n*4
}}。在这种特殊情况下,乘法是不必要的,但它不会影响代码生成,因为汇编程序将为0
计算并替换0*4
而2
替换0*4+2
。< / p>