[英]Embedded assembly in C (DOS) - illegal instruction
我正在嘗試重新編程指令向量表。 這是我使用的代碼:
#include <stdio.h>
int a=1;
void func();
void keyboard()
{
printf("\n\nkeyboard!!!\n");
a=0;
asm{iret}
}
int main ()
{
printf("starting...");
func();
return 0;
}
int vectorcs = 0;
int vectorip = 0;
void func()
{
printf("\n*****\n");
asm{
cli
mov ax,0
mov es,ax
mov bx,36
mov ax,word ptr es:[bx]
mov vectorip,ax
push ax
mov ax,word ptr es:[bx+2]
mov vectorcs,ax
push ax
mov ax,cs
mov word ptr es:[bx],offset keyboard
mov es:[bx+2],ax
sti
}
printf("\n%d %d\n",vectorip,vectorcs);
while (a) {
}
asm {
cli
mov es,bx
mov bx,36
pop ax
mov word ptr es:[bx+2],ax
}
asm{
pop ax
mov word ptr es:[bx],ax
sti
}
}
我正在使用Turbo C ++ 3.0當我嘗試運行這個程序時,“16位MS-DOS子系統:NTVDM CPU遇到了非法指令。” 出現。 然后它顯示CS,OP和IP寄存器的內容。 我不能繼續這個計划。 有什么建議么?
你正在做的事情有多種原因:
interrupt
關鍵字聲明它們。 最后他們會為你而iret
。 volatile
,否則您可能會被編譯器錯誤地優化對它們的訪問。 asm
阻塞堆棧指針。 第一個塊退出,堆棧上有幾個額外的單詞。 這對編譯器來說可能完全出乎意料,可能會破壞您的程序。 可能還有其他問題,但我不打算用編譯器文檔檢查哪些寄存器必須由內聯匯編塊保存。 我完全避免這樣做,而是選擇setvect()
函數。 InDos
標志變量實現的,但是當InDos
= 0時,並非所有人都可以安全地調用。 在這個問題的答案中,了解如何更改中斷向量,定義中斷服務程序並從中調用DOS函數,所有這些都使用Turbo C.
您可能還會發現此問題及其答案有用。
編輯 :
如果沒有dos.h的內聯asm功能,你就是這樣做的:
#include <stdio.h>
volatile int a = 1;
void interrupt (*pOldInt9)(void);
void func(void);
void interrupt keyboard(void)
{
printf("\n\nkeyboard!!!\n");
asm {
in al, 0x60
in al, 0x61
mov ah, al
or al, 0x80
out 0x61, al
mov al, ah
out 0x61, al
}
a = 0;
asm {
mov al, 0x20
out 0x20, al
}
}
int main(void)
{
printf("starting...");
func();
return 0;
}
void func(void)
{
printf("\n*****\n");
asm {
push bx
push es
mov bx, 9 * 4
mov ax, 0
mov es, ax
cli
mov ax, es:[bx]
mov word ptr pOldInt9, ax
mov word ptr es:[bx], offset keyboard
mov ax, es:[bx + 2]
mov word ptr pOldInt9[2], ax
mov es:[bx + 2], cs
sti
pop es
pop bx
}
while (a) {}
asm {
push bx
push es
mov bx, 9 * 4
mov ax, 0
mov es, ax
cli
mov ax, word ptr pOldInt9
mov es:[bx], ax
mov ax, word ptr pOldInt9[2]
mov es:[bx + 2], ax
sti
pop es
pop bx
}
}
asm {
cli
mov es,bx
mov bx,36
pop ax
mov word ptr es:[bx+2],ax
}
在該代碼之前bx
包含什么?
void keyboard()
{
printf("\n\nkeyboard!!!\n");
a=0;
asm{iret}
}
此函數已設置您未正確銷毀的堆棧框架。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.