/**********************027 命令行变元********************************
* 使用,命令行变元写一个小程序cuntdown。 程序对来自命令行的值连续减
* 量,达到零时产生蜂鸣。
* C语言精彩编程百例 第27*/
//Countdown program
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>
int main(int argc,char* argv[])
{
int disp,count;
if(argc<2)
{
printf("You must enter the length of the count\n");
printf("on the command line.Try again\n");
exit(1);
}
if (argc==3 && !strcmp(argv[1],"display"))
disp = 1;
else
disp=0;
for(count = atoi(argv[2]);count;--count)
if(disp==1)
printf("%d\n",count);
putchar('\a');
printf("Down");
return 0;
}
对应的汇编
.file "027.c"
.def ___main; .scl 2; .type 32; .endef
.text
.align 32
LC0:
.ascii "You must enter the length of the count\12\0"
.align 32
LC1:
.ascii "on the command line.Try again\12\0"
LC2:
.ascii "display\0"
LC3:
.ascii "%d\12\0"
LC4:
.ascii "Down\0"
.align 2
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
andl $-16, %esp
movl $0, %eax
movl %eax, -12(%ebp)
movl -12(%ebp), %eax
call __alloca
call ___main
cmpl $1, 8(%ebp) # if argc<2
jg L74
subl $12, %esp # printf
pushl $LC0
call _printf
addl $16, %esp
subl $12, %esp # printf
pushl $LC1
call _printf
addl $16, %esp
subl $12, %esp # exit(1)
pushl $1
call _exit
L74:
cmpl $3, 8(%ebp) # if argc==3
jne L75
subl $8, %esp # 准备调用_strcmp
pushl $LC2 # "display"
movl 12(%ebp), %eax # eax=argv
addl $4, %eax # eax=argv+4
pushl (%eax) # argv[1]
call _strcmp
addl $16, %esp # 调整堆栈
testl %eax, %eax # if strcmp
jne L75
movl $1, -4(%ebp) # disp =1
jmp L76
L75:
movl $0, -4(%ebp) # disp =0
L76:
subl $12, %esp # 准备调用 atoi
movl 12(%ebp), %eax # eax=argv
addl $8, %eax # argv+8
pushl (%eax) # argv[2]
call _atoi
addl $16, %esp # 平衡堆栈
movl %eax, -8(%ebp) # count = atoi(argv[2])
L77:
cmpl $0, -8(%ebp) # if count
jne L80
jmp L78
L80:
cmpl $1, -4(%ebp) # if disp=1
jne L79
subl $8, %esp # printf
pushl -8(%ebp)
pushl $LC3
call _printf
addl $16, %esp
L79:
leal -8(%ebp), %eax # &count
decl (%eax) # count--
jmp L77
L78:
subl $12, %esp # putchar
pushl $7
call _putchar
addl $16, %esp
subl $12, %esp
pushl $LC4
call _printf # printf
addl $16, %esp
movl $0, %eax
leave
ret
.def _putchar; .scl 2; .type 32; .endef
.def _atoi; .scl 2; .type 32; .endef
.def _strcmp; .scl 2; .type 32; .endef
.def _exit; .scl 2; .type 32; .endef
.def _printf; .scl 2; .type 32; .endef
- 命令行变元和函数的参数传递方式比较类似,32位编译器下,都是通过 8(%ebp),12(%ebp)传递的。
- char* argv[], 和 char ** argv 在这里应该是一样的,目前指向地址的指针还没开始研究,后面看见较深入的例子后再深入理解。