繁体   English   中英

GCC内联汇编可以操纵所有寄存器吗?

[英]GCC inline assembly to manipulate all registers?

我试图在C(GCC 4.6.3,x86(64位CPU),Ubuntu 12.04 64位)中进行一些程序集调用,以将寄存器值清零并设置堆栈指针,并最终调用跳转指令。

这就是我得到的:

asm("xor %eax, %eax");
asm("xor %ebx, %ebx");
asm("xor %ecx, %ecx");
asm("xor %edx, %edx");

asm("xor %cs, %cs");
asm("xor %ds, %ds");
asm("xor %es, %es");
asm("xor %fs, %fs");
asm("xor %gs, %gs");
asm("xor %ss, %ss");

asm("xor %esi, %esi");
asm("xor %edi, %edi");
asm("xor %ebp, %ebp");
asm("xor %esp, %esp");

asm("xor %cr0, %cr0");
asm("xor %cr1, %cr1");
asm("xor %cr2, %cr2");
asm("xor %cr3, %cr3");
asm("xor %cr4, %cr4");

asm("xor %cr8, %cr8");

它说Error: operand type mismatch for 'xor'当我尝试编译时,除前四个寄存器外,所有寄存器的Error: operand type mismatch for 'xor'都不Error: operand type mismatch for 'xor' 基本上,我需要将所有寄存器内容清零(不知道该怎么做)。 显然有一个重要的rdx寄存器? 但是我在网上四处张望,找不到列表。

接下来,我需要将堆栈指针设置为特定的内存位置。 我怎样才能做到这一点?

最后,我需要调用jump指令并转到特定的存储位置。 我怎样才能做到这一点?

感谢您提供的所有帮助!

您不能直接操纵cs,ds,es,fs,gs,ss寄存器的值,以将它们清零以将零值从eax,ebx,ecx,edx,esi,edi,esp等寄存器中移出:

asm("xor %eax, %eax");
asm("mov %ds, %eax");

仍然,如果使用E前缀将二进制文件编译为64位,则仅访问寄存器的低32位。 上半部分不会被清零。 要编码64位汇编,请使用R前缀,例如rax。 然后,例如,如果您尝试使用自己的调用堆栈纯粹在汇编中制作自己的C样式函数,并使用32位寄存器并在64位模式下运行它,则会崩溃。

您绝对应该了解使用推入和弹出指令的知识,并且应该在任何内联汇编之前备份在C代码中更改的所有寄存器,然后在之后进行恢复。 如果您不这样做,您的程序集将使您的C代码混乱,并且或多或少会随机崩溃。 例如:

// pack them up
asm("push %eax");
asm("push %ds");
// do something
asm("xor %eax, %eax");
asm("mov %ds, %eax");
// restore them back in opposite order (it's a stack)
asm("pop %ds");
asm("pop %eax");

看这里

接下来,您甚至不能将值移到CS:IP寄存器中,但是可以使用跳转,调用和ret系列指令间接修改其值,但是您不能在代码中这样做,因为您的代码将跳转到(随机)(如果将地址输出归零,则为零)地址,它将崩溃。

有关CS:IP的更多信息,请参见此链接:在汇编语言中更改CS:IP

主要问题是xor或不能在段或控制寄存器上进行操作。 还要注意,归零控制寄存器只能在内核模式下完成,而归零对它们而言仍然没有意义。

此外,gcc内联asm拥有自己独特的语法,可能很容易在单独的asm文件中编写此代码。

您应该阅读intel手册和gcc手册。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM