在需要传入命令行参数时,程序如何取得这些参数呢? 在高级语言程序中,例如C,可以通过main函数的提供参数得到,而在汇编语言中取得这些参数并不是这么简单。这些参数会被保存在栈中,压栈顺序和参数的声明顺序相反,先把指向环境变量的envp压如栈中,然后压如一个全0,区别开环境变量和命令行参数。然后是指向各个命令行参数的指针数组argv,最后才把参数个数argc压如。这样当程序执行时,栈中存放的数据如下:
数据: 地址:
envp[M] <------ (N+1)*4+(M+1)*4
.............
.............
envp[1] <------ (N+1)*4+8(%esp)
envp[0] <------ (N+1)*4+4(%esp)
argv[N] <------ (N+1)*4(%esp)
.............
.............
argv[1] <------ 8(%esp)
argv[0] <------ 4(%esp)
argc <------ (%esp)
下面的一个简单的例子,显示所有的命令行参数。
.text
.globl _start

_start:
popl %ecx
vnext:
popl %ecx
test %ecx, %ecx
jz exit
movl %ecx, %ebx
xorl %edx, %edx

strlen:
movb (%ebx), %al
inc %edx
inc %ebx
test %al, %al
jnz strlen
movb $10, -1(%ebx)
movl $4, %eax # 系统调用号(sys_write)
movl $1, %ebx # 文件描述符(stdout)
int $0x80
jmp vnext
exit:
movl $1,%eax # 系统调用号(sys_exit)
xorl %ebx, %ebx # 退出代码
int $0x80
ret
用gas汇编代码:
as -o args.o args.s
使用ld连接成可执行文件:
ld -s -o args args.o
执行程序:
[smallcat@smallcat code]$ ./args Linux Windows
./args
Linux
Windows
envp[M] <------ (N+1)*4+(M+1)*4
.............
.............
envp[1] <------ (N+1)*4+8(%esp)
envp[0] <------ (N+1)*4+4(%esp)
argv[N] <------ (N+1)*4(%esp)
.............
.............
argv[1] <------ 8(%esp)
argv[0] <------ 4(%esp)
argc <------ (%esp)
下面的一个简单的例子,显示所有的命令行参数。





























用gas汇编代码:





