汇编器步进模式中断处理程序

问题描述 投票:0回答:1

我正在 x86 架构汇编器中编写步进模式中断处理程序,但不知道如何查找并打印出

mov byte ptr [bx]
bx
寄存器。

到目前为止,我已经有了这个,理论上它应该可以工作,但事实并非如此。输出应如下所示:

0000:0128  C60723  mov byte ptr [bx], 23h ; bx= 0001, [bx]=12


.model small
.stack 100h
.data
    senasIP dw ?
    senasCS dw ?
    
    regAX dw ?
    regBX dw ?
    regCX dw ?
    regDX dw ?
    regSP dw ?
    regBP dw ?
    regSI dw ?
    regDI dw ?
    
    baitas1 db ?
    baitas2 db ?
    baitas3 db ?
    baitas4 db ?
    baitas5 db ?
    baitas6 db ?
    
    zingsn_pranesimas db "Zingsninis pertraukimas: $"
    mov_bx_kabl       db "MOV bx, $"
    bx_lygu db "bx=$"
    enteris db 13,10,"$"
.code
    mov ax, @data
    mov ds, ax
    
    mov ax, 0
    mov es, ax ;Extra segmentas prasides ten pat kur vektoriu lentele
                ;To reikia, kad galetume prieiti prie vektoriu lenteles baitu reiksmiu
    
    mov ax, es:[4]
    mov bx, es:[6]
    mov senasCS, bx
    mov senasIP, ax ;neisikeliam tiesiai, nes nera perdavimo is atminties i atminti (butina panaudoti registrus, isimtis eilutines komandos, bet jas panaudoti butu sudetingiau)

;===================PERIMAME PERTRAUKIMA==========================
    mov ax, cs
    mov bx, offset pertraukimas
    
    mov es:[4], bx
    mov es:[6], ax

;=================AKTYVUOJAME ZINGSNINI REZIMA===================
    pushf ;PUSH SF
    pop ax
    or ax, 100h ;0000 0001 0000 0000 (TF=1, kiti lieka kokie buvo)
    push ax
    popf  ;POP SF ;>Zingsninis rezimas ijungiamas po sios komandos ivykdymo - ivykdzius kiekviena sekancia komanda ivyks zingsninis pertraukimas

;==================BELEKOKIOS KOMANDOS====================
    mov byte ptr [bx],23h
    mov bx,001h
;==================ISJUNGIAME ZINGSNINI REZIMA======================
    pushf
    pop  ax
    and  ax, 0FEFFh ;1111 1110 1111 1111 (nuliukas priekyj F, nes skaiciai privalo prasideti skaitmeniu, ne raide) - TF=0, visi kiti liks nepakeisti
    push ax
    popf ;
    
    mov ax, senasIP
    mov bx, senasCS
    mov es:[4], ax
    mov es:[6], bx
    
uzdaryti_programa:
    mov ah, 4Ch
    int 21h
    
    
    
    
    
;==================================================================
;Pertraukimo apdorojimo procedura
;==================================================================
pertraukimas:   
    ; Save register values
    mov regAX, ax               
    mov regBX, bx
    mov regCX, cx
    mov regDX, dx
    mov regSP, sp
    mov regBP, bp
    mov regSI, si
    mov regDI, di
    
    ; Retrieve instruction bytes at CS:IP
    pop si ; Get IP value
    pop di ; Get CS value
    push di ; Restore CS
    push si ; Restore IP

    ; Copy bytes into local storage
    mov al, cs:[si]       ; First byte of instruction
    mov ah, cs:[si+1]     ; Second byte of instruction
    mov baitas1, al
    mov baitas2, ah

    cmp al, 0C6h          ; Check for opcode `C6`
    jne grizti_is_pertraukimo
    cmp ah, 07h           ; Check for ModRM byte `07` (BX addressing mode)
    jne grizti_is_pertraukimo
    
    ; Print the recognized instruction
    mov ah, 9
    mov dx, offset zingsn_pranesimas
    int 21h
    
    ; Print CS:IP
    mov ax, di
    call printAX
    mov ah, 2
    mov dl, ":"
    int 21h
    mov ax, si
    call printAX
    call printSpace
    
    ; Print machine code bytes
    mov ah, baitas1
    call printAL
    mov al, baitas2
    call printAL
    mov al, cs:[si+2]     ; Immediate byte
    call printAL
    call printSpace
    call printSpace
    
    ; Print assembly mnemonic
    mov ah, 9
    mov dx, offset mov_bx_kabl ; Text: `MOV byte ptr [BX],`
    int 21h
    
    mov al, cs:[si+2]     ; Immediate value
    call printAL
    
    mov ah, 2
    mov dl, "h"           ; Append `h` for hexadecimal notation
    int 21h
    
    call printSpace
    call printSpace
    
    ; Print the value of BX register before execution
    mov ah, 9
    mov dx, offset bx_lygu ; Text: `bx=`
    int 21h
    mov ax, regBX
    call printAX
    
    ; Print newline
    mov ah, 9
    mov dx, offset enteris
    int 21h
    
grizti_is_pertraukimo:
    mov ax, regAX
    mov bx, regBX
    mov cx, regCX
    mov dx, regDX
    mov sp, regSP
    mov bp, regBP
    mov si, regSI
    mov di, regDI
IRET ; Return from interrupt handler

;===================PAGALBINES pertraukime naudojamos proceduros================

;>>>Spausdinti AX reiksme
printAX:
    push ax
    mov al, ah
    call printAL
    pop ax
    call printAL
RET

;>>>>Spausdink tarpa
printSpace:
    push ax
    push dx
        mov ah, 2
        mov dl, " "
        int 21h
    pop dx
    pop ax
RET

;>>>Spausdinti AL reiksme
printAL:
    push ax
    push cx
        push ax
        mov cl, 4
        shr al, cl
        call printHexSkaitmuo
        pop ax
        call printHexSkaitmuo
    pop cx
    pop ax
RET

;>>>Spausdina hex skaitmeni pagal AL jaunesniji pusbaiti (4 jaunesnieji bitai - > AL=72, tai 0010)
printHexSkaitmuo:
    push ax
    push dx
    
    and al, 0Fh ;nunulinam vyresniji pusbaiti AND al, 00001111b
    cmp al, 9
    jbe PrintHexSkaitmuo_0_9
    jmp PrintHexSkaitmuo_A_F
    
    PrintHexSkaitmuo_A_F: 
    sub al, 10 ;10-15 ===> 0-5
    add al, 41h
    mov dl, al
    mov ah, 2; spausdiname simboli (A-F) is DL'o
    int 21h
    jmp PrintHexSkaitmuo_grizti
    
    
    PrintHexSkaitmuo_0_9: ;0-9
    mov dl, al
    add dl, 30h
    mov ah, 2 ;spausdiname simboli (0-9) is DL'o
    int 21h
    jmp printHexSkaitmuo_grizti
    
    printHexSkaitmuo_grizti:
    pop dx
    pop ax
RET

END

assembly x86-16 tasm dosbox
1个回答
0
投票
mov ax, cs
mov bx, offset pertraukimas

mov es:[4], bx
mov es:[6], ax

在禁用中断的情况下修改中断向量总是更好。这将避免使用不完整向量的任何风险。这就是为什么我写道:

cli
mov word [es:4], pertraukimas
mov [es:6], cs
sti

popf
mov byte ptr [bx],23h
mov bx,001h

一旦您的

popf
指令设置了单步标志TF,CPU将在执行以下指令后自动生成异常。需要注意的是,实际设置 TF 的指令不会生成异常。因此,在 popf
 之后,不会立即调用特殊处理程序,但在执行 
mov byte ptr [bx],23h 后,会出现 is
。在我的程序中,我通过插入 
nop
:
解决了这个问题

popf ; This sets TF=1 nop ; Here happens the very first trap and CS:IP point at mov byte [bx], 23h ; ... this instruction mov bx, 0001h
处理器放在堆栈上的 CS:IP 值并不代表刚刚运行的指令的地址,而是代表后续指令的地址。

我编写的演示程序是一个 .COM 可执行文件,其中所有段寄存器开始时都彼此相等。单步处理程序的工作原理如问题所示。我在DOSBox 0.74环境下测试过。

我得到的输出:

Zingsninis pertraukimas: 0192:012A C60723 MOV bx, 23h bx=0070

ORG 256 xor ax, ax mov es, ax mov ax, [es:4] mov bx, [es:6] mov [senasIP], ax mov [senasCS], bx cli mov word [es:4], pertraukimas mov [es:6], cs sti pushf : pop ax : or ax, 0100h : push ax : popf ;=============================================== nop mov byte [bx], 23h mov bx, 0001h ;================================================= pushf : pop ax : and ax, 0FEFFh : push ax : popf cli mov ax, [senasIP] mov [es:4], ax mov ax, [senasCS] mov [es:6], ax sti mov ax, 4C00h int 21h ;================================================================== ;Pertraukimo apdorojimo procedura ;================================================================== pertraukimas: push es ax bx cx dx si di bp mov bp, sp les si, [bp+16] mov ax, [es:si] cmp ax, 07C6h ; Check for opcode `C6` and ModRM byte `07` (BX addressing mode) jne grizti_is_pertraukimo mov ah, 9 mov dx, zingsn_pranesimas int 21h mov ax, es call printAX mov ah, 2 mov dl, ":" int 21h mov ax, si call printAX call printSpace mov al, 0C7h call printAL mov al, 07h call printAL mov al, [es:si+2] ; Immediate byte call printAL call printSpace call printSpace mov ah, 9 mov dx, mov_bx_kabl ; Text: `MOV byte ptr [BX],` int 21h mov al, [es:si+2] ; Immediate value call printAL mov ah, 2 mov dl, "h" ; Append `h` for hexadecimal notation int 21h call printSpace call printSpace ; Print the value of BX register before execution mov ah, 9 mov dx, bx_lygu ; Text: `bx=` int 21h mov ax, [bp+10] ; Pushed BX call printAX mov ah, 9 mov dx, enteris int 21h grizti_is_pertraukimo: pop bp di si dx cx bx ax es iret ;===================PAGALBINES pertraukime naudojamos proceduros================ printSpace: push ax dx mov ah, 2 mov dl, " " int 21h pop dx ax ret printAX: push ax mov al, ah call printAL pop ax printAL: push ax cx push ax mov cl, 4 shr al, cl call printHexSkaitmuo pop ax call printHexSkaitmuo pop cx ax ret printHexSkaitmuo: push ax dx and al, 15 cmp al, 10 jb .num add al, 65-10-48 .num: add al, 48 mov dl, al mov ah, 2 int 21h pop dx ax ret ; ------------------------------------ senasIP: dw ? senasCS: dw ? zingsn_pranesimas: db "Zingsninis pertraukimas: $" mov_bx_kabl: db "MOV bx, $" bx_lygu: db "bx=$" enteris: db 13,10,"$"
我为此使用了一个私有汇编器(类似于 FASM)。请修改 

你的汇编程序可能不允许的任何内容。

© www.soinside.com 2019 - 2024. All rights reserved.