- 论坛徽章:
- 0
|
本帖最后由 true_casey 于 2013-10-18 20:58 编辑
EAX,EBX,ECX,EDX 都作为参数传递的寄存器,但是调用协定规定的是EAX,ECX,EDX作为调用者保存,所以你会在使用EBX传参的函数入口处发现有 PUSH EBX的语句,EAX一般作为系统号,EBX,ECX,EDX 作为参数,使用了EBX,就得PUSH EBX,然后内核的返回值放到EAX,传回来,这里有两个方式:
1.汇编,用一个变量,在pop 之前,保存,大致就像这样,函数的语句:
.................
mov eax,SYS_NR
int 0x80
mov dword [var],eax
..............
如果写成函数的形式:
xxx:
................... ; eax,ecx,edx 不需要保存,由调用者保存
mov eax,SYS_NR
mov ebx,[ebp + xxxx] ; 从堆栈取参数,这里使用了 ebx,所以前面必须要 push ebx
...... ecx
...... edx
int 0x80 ; 返回值在 eax 里,调用者在pop eax 之前将返回值写到赋值的变量内,比如 int a = xxx () ;再pop eax,ecx,edx
...................
ret
2. 内嵌汇编,就是 C里面嵌入汇编,优势显而易见,直接可以用局部变量带回参数,如
/* the syscall argc == 3 */
#define sys_call_3(ret_type,func_name,atype,a,btype,b,ctype,c) \
ret_type func_name(atype a,btype b,ctype c ) \
{\
unsigned long __res;\
__asm__ ("int $0x80"\
:"=a"(__res)\
:"a"(__NR_##func_name),"b"(a),"d"(b),"c"(c));\
return (__res);\
}
第2种很方便,所以大部分都是第2种方式。。。。
|
|