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



与前面的版本不同,这个是使用libc库版本的显示命令行参数程序,因为main函数并不是程序的入口点,而是由libc库的代码调用,所以命令行参数在栈上的位置有不同,先看示例程序:

[SECTION .data]			; Section containing initialised data
		
ArgMsg	db "Argument %d: %s",10,0
		
[SECTION .bss]			; Section containing uninitialized data
	
		
[SECTION .text]			; Section containing code
					
global main			; Required so linker can find entry point
extern printf			; Notify linker that we're calling printf
		
main:
    push ebp	; Set up stack frame for debugger
	mov ebp,esp
	push ebx	; Program must preserve ebp, ebx, esi, & edi
	push esi
	push edi
;;; Everything before this is boilerplate; use it for all ordinary apps!	

	mov edi,[ebp+8]	 ; Load argument count into EDI
	mov ebx,[ebp+12] ; Load pointer to argument table into EBX
	xor esi,esi	 ; Clear ESI to 0
.showit:
	push dword [ebx+esi*4]	; Push addr. of an argument on the stack
	push esi	; Push argument number
	push ArgMsg	; Push address of display string
	call printf	; Display the argument # and argument
	add esp,12 	; Stack cleanup: 3 parms x 4 bytes = 12
	inc esi		; Bump argument # to next argument
	dec edi		; Decrement argument counter by 1
	jnz .showit	; If argument count is 0, we're done
	
;;; Everything after this is boilerplate; use it for all ordinary apps!
	pop edi		; Restore saved registers
	pop esi
	pop ebx
	mov esp,ebp	; Destroy stack frame before returning
	pop ebp
	ret		; Return control to Linux

程序分析:
main:
    push ebp //保存旧的ebp
 mov ebp,esp //ebp = esp,保存栈指针到ebp
 push ebx //保存ebx
 push esi //保存esi
 push edi //保存edi

 mov edi,[ebp+8]  //ebp+4保存的是调用main函数后的返回地址,ebp+8,是main函数左边的第一个参数:argc,即命令行参数个数
 mov ebx,[ebp+12] //ebp+12保存的是argv,就是命令行参数字符串指针数组。
 xor esi,esi  //esi=0
.showit:
 push dword [ebx+esi*4] //把字符串参数压入堆栈
 push esi //压入参数编号(索引值)
 push ArgMsg //格式化字符串
 call printf //调用printf,显示这个字符串参数信息
 add esp,12  //清理栈
 inc esi  //esi=esi+1,下一个参数
 dec edi  //edi=edi-1,用于控制循环次数
 jnz .showit //如果edi不等于0,则继续循环,否则结束。循环次数是命令行参数个数。
 
 pop edi  //恢复edi寄存器
 pop esi      //恢复esi寄存器
 pop ebx     //恢复ebx寄存器 
 mov esp,ebp //esp=ebp,恢复函数调用开始时栈指针位置
 pop ebp //恢复ebp
 ret 

测试:

[root@bogon showargs3]# make
nasm -f elf -g -F stabs showargs3.asm
gcc showargs3.o -o showargs3
[root@bogon showargs3]# ./showargs3 p1 p2 p3 p4 p5
Argument 0: ./showargs3
Argument 1: p1
Argument 2: p2
Argument 3: p3
Argument 4: p4
Argument 5: p5


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值