|
很多人都知道,函数调用中,函数的参数是通过压栈出栈传递的。下面通过代码来验证压栈过程。
代码分两部分,参考了其他作者的代码后修改的。
1. 首先验证操作系统的栈的增长方向;
2. 汇编语言将参数压栈,然后调用C语言的函数。
代码1: 函数的临时变量从栈中分配内存,而static变量只初始化一次。利用这两个基本原理验证堆栈增长方向。
代码如下:
#include <stdio.h> int find_stack_direction(); int main() { int temp; temp = find_stack_direction(); if(0 == temp) printf("Ubuntu's stack is increating!\n"); else printf("Ubuntu's stack is decreasing!\n"); return 1; } int find_stack_direction() { static int* addr = NULL; int anything; if(NULL == addr) { addr = &anything; find_stack_direction(); } else { if(addr > &anything) return 1; else return 0; } }
代码2中,汇编程序主动压栈两个参数,调用C语言函数,函数从栈中取参数运算后返回。
汇编代码如下:
extern choose [section .data] num1st dd 5 num2nd dd 9 [section .text] global _start global myprint _start: push dword[num1st] push dword[num2nd] call choose add esp, 8 mov ebx, 0 mov eax, 1 int 0x80 myprint: mov edx, [esp+8] mov ecx, [esp+4] mov ebx, 1 mov eax, 4 int 0x80 ret
C语言代码如下:
void myprint(char* msg, int len); int choose(int a, int b) { char temp; if (a < b) { myprint("the 1st one choosed!\n", 21); } else { myprint("the 2nd one choosed!\n", 21); } a += 48; b += 48; temp = (char)a; myprint(&temp, 1); myprint("\n",2); temp = (char)b; myprint(&temp, 1); myprint("\n",2); return 0; }
由于我用的是64为ubuntu,在用NASM和GCC编译的时候出现编译通过,不能链接的错误。Google后找到原因:NASM编译出32位目标文件,GCC在64位机默认编译出64位目标文件,导致两个目标文件无法链接。解决方法是在GCC编译命令里添加 -m32 参数,LD链接命令参数添加 -m elf_i386
代码1的参考作者不记得了,代码2参考于Orange's;链接错误参考于http://www.cnblogs.com/chenchenluo/archive/2012/04/02/2421457.html
|