究竟C中的函数调用时怎么回事呢?我们很像知道,因此做了下面的实验。

32 篇文章 0 订阅

这一次比之前的弄得明白一点了,希望不会误导大家!

#include <stdio.h>

void ff(char* s) {printf("%s", s);}

void main(void){
	void fff(char* s) {printf("%s", s);}
	ff("Hello, C language!\n");
	fff("Hello, World!\n");
	char* s0 = "This is C language!\n";
	char* s1 = "This is C language too!\n";
	char* s2 = "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n";
	asm("movl %%eax, (%%esp)\n""call _printf"::"a"(s2));
	asm("movl %%eax, (%%esp);""call _ff"::"a"(s0));
	asm("movl %%eax, (%%esp);""call *%%ebx"::"a"(s1),"b"(fff));
	asm("movl %%eax, (%%esp)\n""call _printf"::"a"(s2));
	asm("movl %%eax, (%%esp);""call _ff"::"a"(s0));
	asm("movl %%eax, (%%esp);""call *%%ebx"::"a"(s1),"b"(fff));
	asm("movl %%eax, (%%esp)\n""call _printf"::"a"(s2));
	asm("movl %%eax, (%%esp);""call _ff"::"a"(s0));
	asm("movl %%eax, (%%esp);""call *%%ebx"::"a"(s1),"b"(fff));
	asm("movl %%eax, (%%esp)\n""call _printf"::"a"(s2));
	asm("movl %%eax, (%%esp);""call _ff"::"a"(s0));
	asm("movl %%eax, (%%esp);""call *%%ebx"::"a"(s1),"b"(fff));
}

至于代码中为什么不用压栈指令,而是用数据传送指令使参数入栈,我就明白了,只是机械地参考了反汇编后的代码。

#include <stdio.h>

void ff(char* s) {}

void f(void){
	void fff(char* s) {}
	ff("Hello, World!\n");
	fff("Hello, World!\n");
}

/*
test506.o:     file format pe-i386


Disassembly of section .text:

00000000 <_ff>:
   0:	55                   	push   %ebp
   1:	89 e5                	mov    %esp,%ebp
   3:	90                   	nop
   4:	5d                   	pop    %ebp
   5:	c3                   	ret    

00000006 <_fff.1887>:
   6:	55                   	push   %ebp
   7:	89 e5                	mov    %esp,%ebp
   9:	83 ec 04             	sub    $0x4,%esp
   c:	89 4d fc             	mov    %ecx,-0x4(%ebp)
   f:	90                   	nop
  10:	c9                   	leave  
  11:	c3                   	ret    

00000012 <_f>:
  12:	55                   	push   %ebp
  13:	89 e5                	mov    %esp,%ebp
  15:	83 ec 14             	sub    $0x14,%esp
  18:	8d 45 08             	lea    0x8(%ebp),%eax
  1b:	89 45 fc             	mov    %eax,-0x4(%ebp)
  1e:	c7 04 24 00 00 00 00 	movl   $0x0,(%esp)
  25:	e8 d6 ff ff ff       	call   0 <_ff>
  2a:	8d 45 fc             	lea    -0x4(%ebp),%eax
  2d:	c7 04 24 00 00 00 00 	movl   $0x0,(%esp)
  34:	89 c1                	mov    %eax,%ecx
  36:	e8 cb ff ff ff       	call   6 <_fff.1887>
  3b:	90                   	nop
  3c:	c9                   	leave  
  3d:	c3                   	ret    
  3e:	90                   	nop
  3f:	90                   	nop
*/

下面是之前的,谨慎参考,代码有误。

这里"addl $(4 * 1), %esp"似乎是多余的,但我不确定。不过用jmp就不能成功返回到汇编下面的语句继续执行。也许是要在前面加入"pushl _retaddr"之类的语句把,不过这里可能要在紧邻的下面加入retaddr:之类的标号,才能正确的返回吧。留在明天再尝试吧,也好凑个篇幅。

 

#include <stdio.h>

//这里对函数或是变量都不能定义为局部的,即不能再main内部定义
//否则程序因未定义变量而不能连接

void f(int a){
	printf("0x%x\n", a);
}

int a = 100;
const char* str = "Hello, world!\t%d\t\n";

int main(void){
	printf("0x%x\n", f);
	asm("pushl $256;"
		"call _f;"
		"addl $(4 * 1), %esp");
	asm("pushl $15;"
		"call 0x401460;"
		"addl $(4 * 1), %esp");
	asm("pushl _a\n"
		"pushl _str\n"
		"call _printf\n"
		"addl $(8 * 1), %esp");
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_39410618

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值