c语言compile是什么意思英语,什么c代码编译成`call *%eax`之类的东西?(What c code would compile to something like `call *%eax...

什么c代码编译成`call *%eax`之类的东西?(What c code would compile to something like `call *%eax`?)

我正在使用c和汇编,我在一些地方看到过call *%eax 。 我想写一个小的c程序,可以编译成这样的东西,但我卡住了。

我正在考虑编写一些汇编代码,就像在这个问题中一样: x86汇编指令:call * Reg仅在我的情况下使用AT&T语法来获取一个带有调用的小例子。 但是,这不能解决我对什么样的c代码编译的问题?

我知道这是对eax指向的地址的调用。

I'm working with c and assembly and I've seen call *%eax in a few spots. I wanted to write a small c program that would compile to something like this, but I'm stuck.

I was thinking about just writing up some assembly code like in this question: x86 assembly instruction: call *Reg only using AT&T syntax in my case to get a small example with the call in it. However, that wouldn't solve my burning question of what kind of c code compiles to that?

I understand that it is a call to the address that eax is pointing to.

原文:https://stackoverflow.com/questions/21324087

更新时间:2019-12-25 08:26

最满意答案

尝试这个

#include

typedef void (*FuncPtr)(void);

void _Func(void){

printf("Hello");

}

int main(int argc, char *argv[]){

register FuncPtr func asm ("eax") = _Func;

func();

return 0;

}

及其相关组件:

.file "functorTest.c"

.section .rdata,"dr"

LC0:

.ascii "Hello\0"

.text

.globl __Func

.def __Func; .scl 2; .type 32; .endef

__Func:

pushl %ebp

movl %esp, %ebp

subl $24, %esp

movl $LC0, (%esp)

call _printf

leave

ret

.def ___main; .scl 2; .type 32; .endef

.globl _main

.def _main; .scl 2; .type 32; .endef

_main:

pushl %ebp

movl %esp, %ebp

andl $-16, %esp

call ___main

movl $__Func, %eax

call *%eax ; see?

movl $0, %eax

movl %ebp, %esp

popl %ebp

ret

.def _printf; .scl 2; .type 32; .endef

Try this

#include

typedef void (*FuncPtr)(void);

void _Func(void){

printf("Hello");

}

int main(int argc, char *argv[]){

register FuncPtr func asm ("eax") = _Func;

func();

return 0;

}

And its relative assembly:

.file "functorTest.c"

.section .rdata,"dr"

LC0:

.ascii "Hello\0"

.text

.globl __Func

.def __Func; .scl 2; .type 32; .endef

__Func:

pushl %ebp

movl %esp, %ebp

subl $24, %esp

movl $LC0, (%esp)

call _printf

leave

ret

.def ___main; .scl 2; .type 32; .endef

.globl _main

.def _main; .scl 2; .type 32; .endef

_main:

pushl %ebp

movl %esp, %ebp

andl $-16, %esp

call ___main

movl $__Func, %eax

call *%eax ; see?

movl $0, %eax

movl %ebp, %esp

popl %ebp

ret

.def _printf; .scl 2; .type 32; .endef

2014-01-24

相关问答

CMP减去操作数并设置标志。 即,如果差值为零(操作数相等),则设置零标志。 当AND运算结果为零时, TEST设置零标志ZF 。 如果两个操作数相等,当它们都为0时,它们的按位AND为零。 TEST结果中设置最高有效位时, TEST也设置符号标志SF ,当设置位数为偶数时, TEST也设置奇偶校验标志PF 。 JE [跳转等于]测试零标志,如果标志置位,则跳转。 JE是JZ的别名[Jump if Zero],所以反汇编器不能根据操作码选择一个。 JE被命名为这样,因为如果CMP的参数相等,则设置

...

这些是缓冲区溢出保护方法,与编译器优化无关。 MSVC将(如果您指定/GS开关)将安全cookie推送到返回地址附近的堆栈,以便可以检测到堆栈损坏的常见情况。 堆栈损坏可能是由以下错误代码引起的: char buff[5];

strcpy (buff, "Man, this string is waaay too long!!");

或恶意用户利用坏的编码习惯,如使用scanf ("%s", myBuff)进行用户输入。 这样精心制作的攻击可以让你的程序抛弃你可能不想要的东西。 通过将cooki

...

这是一个NOP 。 以下是通常用作NOP 。 他们都做同样的事情,但它们导致不同长度的机器码。 根据对齐要求,选择其中之一: xchg eax, eax = 90

mov eax, eax = 89 C0

lea eax, [eax + 0x00] = 8D 40 00

It is a NOP. The following are typcially used as NOP. They all do the same thing but they resul

...

它测试eax是否为0或以上或以下。 在这种情况下,如果eax为0,则跳转。 It tests whether eax is 0, or above, or below. In this case, the jump is taken if eax is 0.

该行: mov eax,dword ptr [edi]

将简单地加载存储在地址edi处的任何东西。 所以这是一个简单的数据加载。 由于您没有显示地址edi ( 0x6090F434 )处的内容,因此我们无法确切知道eax是什么。 基于给出的C ++代码,它看起来像edi是num字段的地址。 所以它将num读入一个寄存器,然后将它与0xFFFFFFFF进行比较,这是INVALID_FLAG常量。 The line: mov eax,dword ptr [edi]

will simply load

...

文档: http : //gcc.gnu.org/onlinedocs/gcc/Local-Reg-Vars.html#Local-Reg-Vars 尝试这个 #include

typedef void (*FuncPtr)(void);

void _Func(void){

printf("Hello");

}

int main(int argc, char *argv[]){

register FuncPtr func asm ("eax") = _Func;

...

您可以将结果放入另一个寄存器中,而不是EAX,例如lea edx, eax + ebx 。 add不了。 lea还可以有另外的第三个操作数,比如lea eax, ebp + esi + 12 ,这使得它成为add指令的更方便的选择。 您还可以将某些(字大小)乘法运算与它结合使用,例如lea eax, ebp + eax * 8 。 更不用说它更好地描述了这个意图:) You can put the result into another register than EAX, such as lea

...

移位指令不接受32位寄存器作为其计数操作数 。 你会想使用cl的低位: shl eax, cl

The shift instructions don't accept a 32-bit register as their count operand. You'll want to use the lower bits in cl: shl eax, cl

该名称有点误导,因为您的代码片段中没有浮点运算。 在C中,除零是未定义的行为,这意味着你不能轻易地承担一个特定的行为(或者更准确地说,你必须期望会发生任何事情)。 在x86上,任何东西都是硬件异常。 操作系统的主要职责之一是处理这些硬件异常。 Linux通过将SIGFPE发送到违规进程来处理除以零的处理。 大多数进程在除零后不能继续运行(因为程序继续执行什么值?),因此转储核心并放弃返回值,指示使其中止的信号。 然后你的shell解释你的程序的返回值,并在你的终端上写入Floating point

...

如果您熟悉C / C ++,这里有一个解释。 mov ecx, num相当于: int num;

ecx = & num;

而mov ecx, [num]相当于: int num;

ecx = num;

这里,行mov ecx, num的原因是因为你正在调用系统函数int 0x80 ,这要求ecx包含你的数字的地址。 所以它应该是那样的。 If you are familiar with C/C++, here is an explanation. mov ecx, num is equiva

...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值