32位汇编语言学习笔记(37)--显示命令行参数



这个程序出自《Assembly Language step by step programming with linux》第11章,用于显示程序的命令行参数,首先看代码:

SECTION .data			; Section containing initialised data

	ErrMsg db "Terminated with error.",10
	ERRLEN equ $-ErrMsg
	
SECTION .bss			; Section containing uninitialized data	

; This program handles up to MAXARGS command-line arguments. Change the
; value of MAXARGS if you need to handle more arguments than the default 10.
; In essence we store pointers to the arguments in a 0-based array, with the
; first arg pointer at array element 0, the second at array element 1, etc.
; Ditto the arg lengths. Access the args and their lengths this way:
; 	Arg strings: 		[ArgPtrs + <index reg>*4]
;	Arg string lengths:	[ArgLens + <index reg>*4]
; Note that when the argument lengths are calculated, an EOL char (10h) is
; stored into each string where the terminating null was originally. This
; makes it easy to print out an argument using sys_write. This is not
; essential, and if you prefer to retain the 0-termination in the arguments, 
; you can comment out those lines as indicated.

	MAXARGS   equ  10	; Maximum # of args we support
	ArgCount: resd 1	; # of arguments passed to program
	ArgPtrs:  resd MAXARGS	; Table of pointers to arguments
	ArgLens:  resd MAXARGS	; Table of argument lengths

SECTION .text			; Section containing code

global 	_start			; Linker needs this to find the entry point!
	
_start:
	nop			; This no-op keeps gdb happy...

; Get the command line argument count off the stack and validate it:
	pop ecx 		; TOS contains the argument count
	cmp ecx,MAXARGS		; See if the arg count exceeds MAXARGS
	ja Error		; If so, exit with an error message
	mov dword [ArgCount],ecx ; Save arg count in memory variable

; Once we know how many args we have, a loop will pop them into ArgPtrs:
	xor edx,edx		; Zero a loop counter
SaveArgs:
	pop dword [ArgPtrs + edx*4]  ; Pop an arg into the memory table
	inc edx			; Bump the counter to the next argument
	cmp edx,ecx		; Is the counter = the argumemt count?
	jb SaveArgs		; If not, loop back and do another

; With the argument pointers stored in ArgPtrs, we calculate their lengths:
	xor eax,eax		; Searching for 0, so clear AL to 0
	xor ebx,ebx		; Pointer table offset starts at 0
ScanOne:
	mov ecx,0000ffffh	; Limit search to 65535 bytes max
	mov edi,dword [ArgPtrs+ebx*4] ; Put address of string to search in EDI
	mov edx,edi		; Copy starting address into EDX                                                                                                                                                                                                                                                                                                             
	cld			; Set search direction to up-memory
	repne scasb		; Search for null (0 char) in string at edi
; Comment out the following line if you need mull-terminated arguments:
	mov byte [edi-1],10	; Store an EOL where the null used to be
	sub edi,edx		; Subtract position of 0 from start address
	mov dword [ArgLens+ebx*4],edi	; Put length of arg into table
	inc ebx			; Add 1 to argument counter
	cmp ebx,[ArgCount]	; See if arg counter exceeds argument count
	jb ScanOne		; If not, loop back and do another one

; Display all arguments to stdout:
	xor esi,esi		; Start (for table addressing reasons) at 0
Showem:
	mov ecx,[ArgPtrs+esi*4]	; Pass offset of the message
	mov eax,4		; Specify sys_write call
	mov ebx,1		; Specify File Descriptor 1: Standard Output
	mov edx,[ArgLens+esi*4]	; Pass the length of the message
	int 80H			; Make kernel call
	inc esi			; Increment the argument counter
	cmp esi,[ArgCount]	; See if we've displayed all the arguments
	jb Showem		; If not, loop back and do another
	jmp Exit		; We're done! Let's pack it in!

Error: 	mov eax,4		; Specify sys_write call
	mov ebx,1		; Specify File Descriptor 2: Standard Error
	mov ecx,ErrMsg		; Pass offset of the error message
	mov edx,ERRLEN		; Pass the length of the message
	int 80H			; Make kernel call

Exit:	mov eax,1		; Code for Exit Syscall
	mov ebx,0		; Return a code of zero	
	int 80H			; Make kernel call

程序分析:
 pop ecx   //栈顶是命令行参数的个数
 cmp ecx,MAXARGS  //比较参数的个数与最大参数个数(10)
 ja Error  //如果大于最大参数个数,则跳转到Error
 mov dword [ArgCount],ecx //保存参数个数值到ArgCount变量中

 xor edx,edx  //edx清零,用于循环计数
SaveArgs:
 pop dword [ArgPtrs + edx*4]  //保存命令行参数字符串地址ArgPtrs数组
 inc edx   //edx=edx+1
 cmp edx,ecx  //比较edx和命令行参数个数
 jb SaveArgs  //如果edx<ecx,跳转到SaveArgs,继续循环。

 xor eax,eax  //eax清零,因此al=0
 xor ebx,ebx  //ebx清零,用于循环计数
ScanOne:
 mov ecx,0000ffffh //ecx=65535,限制最大扫描次数
 mov edi,dword [ArgPtrs+ebx*4] //edi= &ArgPtrs[ebx*4]
 mov edx,edi  //edx=edi                                                                                                                                                                                                                                                                                                            
 cld   //清除DF标志,控制扫描字符串从地地址到高地址
 repne scasb  //扫描edi中保存的字符串,到0字符扫描结束。
 mov byte [edi-1],10 //把0字符替换成10(换行符)
 sub edi,edx  //edi=edi-edx,得到字符串长度(包括换行符)
 mov dword [ArgLens+ebx*4],edi //把长度值保存到ArgLens数组中
 inc ebx   //ebx=ebx+1
 cmp ebx,[ArgCount] //比较ebx与ArgCount变量值
 jb ScanOne  //如果循环计数小于参数个数,跳转ScanOne,继续循环

 xor esi,esi  //esi清零
Showem:
 mov ecx,[ArgPtrs+esi*4] //ecx=字符串地址
 mov eax,4  //系统调用sys_write号
 mov ebx,1  //写到标准输出
 mov edx,[ArgLens+esi*4] //字符串长度
 int 80H   //执行系统调用
 inc esi   //esi=esi+1
 cmp esi,[ArgCount]  //比较esi和命令行参数个数
 jb Showem  //如果esi小于命令行参数个数,继续循环
 jmp Exit 

makefie文件内容:

showargs1: showargs1.o
	ld -o showargs1 showargs1.o
showargs1.o: showargs1.asm
	nasm -f elf -g -F stabs showargs1.asm -l showargs1.lst

测试:

[root@bogon showargs1]# make
nasm -f elf -g -F stabs showargs1.asm -l showargs1.lst
ld -o showargs1 showargs1.o
[root@bogon showargs1]# ./showargs1 
./showargs1
[root@bogon showargs1]# ./showargs1 p1 p2 p3
./showargs1
p1
p2
p3



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值