内联汇编跳转错误 [英] Inline Assembly Jump Error

查看:231
本文介绍了内联汇编跳转错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么这个失败,一旦达到MASM JMP?

Why does this fail, once Masm reaches jmp?

struct gdt_entry
{
    unsigned short limit_low;
    unsigned short base_low;
    unsigned char base_middle;
    unsigned char access;
    unsigned char granularity;
    unsigned char base_high;
};

struct gdt_ptr
{
    unsigned short limit;
    unsigned int base;
};

struct gdt_entry gdt[3];
struct gdt_ptr gp;


void gdt_flush()
{
      __asm{
          lgdt [gp]

          mov ax, 0x10
          mov ds, ax
          mov es, ax
          mov fs, ax
          mov gs, ax
          mov ss, ax

          ; push the address on the stack
          push 0x08
          mov eax, offset flush2
          push eax

          ; ret use the previous pushed address
          _emit 0xCB ; far return

      flush2:
          ;ret
   }
}


void gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran)
{

    gdt[num].base_low = (base & 0xFFFF);
    gdt[num].base_middle = (base >> 16) & 0xFF;
    gdt[num].base_high = (base >> 24) & 0xFF;
    gdt[num].limit_low = (limit & 0xFFFF);
    gdt[num].granularity = ((limit >> 16) & 0x0F);
    gdt[num].granularity |= (gran & 0xF0);
    gdt[num].access = access;
}

void gdt_install()
{
    gp.limit = (sizeof(struct gdt_entry) * 3) - 1;
    gp.base = (int)&gdt;
    gdt_set_gate(0, 0, 0, 0, 0);
    gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
    gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
    gdt_flush();
}

`

推荐答案

您转移了堆栈右出其下 - 由RET使用的IP正指向的地方真的太疯狂了。

You shifted the stack right out from under it - the ip used by ret is now pointing somewhere really wild

您还揍栈 - 同样一个接VC使用。 VC推动更多的东西压入堆栈不仅仅是返回IP。执行源和放大器的汇编上市;你会看到。

You still clobber the stack - the same one used by VC. VC pushes more stuff onto the stack than just the return IP. Do a assembler-listing of the source & you'll see.

一个可能性是复制返回地址从栈中所做的更改之前,在结束只是跳转到它指向。

A possibility is to copy the return-address off the stack before you make the changes, and at end to just jump to where it points.

创建一个标记DW来保存地址:

create a labeled dw to store the address:

_asm {
    oldip dd ?      ;this is in cs
    pop eax         ;eip into eax
    push eax        ;leave stack as found
    mov oldip,eax    
    .
    ..your stuff
    .
    jmp far cs:[oldip]     
}

我可能失去了一些东西,但你的$ C $的外观c您是重挫所有段值,除了CS,从而破坏所有访问previously声明的变量无处不在,以及任何返回地址等放入堆栈你的程序上...也许这就是你想要做什么,跳下来code别的地方,你成为孤儿目前的计划...

I may be missing something here, but by the looks of your code you are clobbering all the segment values except cs, thereby destroying all access to previously declared variables everywhere, as well as any return address etc placed on the stack by your program ... maybe that's what you want to do, jumping off to code somewhere else, orphaning your current program ...

上面的片段应该把你回电话与_asm东西功能之后的指令,但上帝知道发生了什么事,然后会发生。

The above fragment should put you back at the instruction following the call to the function with the _asm stuff, but lord knows what's going to happen then.

这篇关于内联汇编跳转错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆