32位汇编语言学习笔记(38)--显示命令行参数(2)
来源:互联网 发布:java从入门到精通mobi 编辑:程序博客网 时间:2024/05/29 18:08
showargs1程序是把命令行参数字符串的地址从栈中拷贝到全局数组变量里,然后把结果显示出来,showargs2程序对此进行了改进,直接从栈上读取命令行参数字符串的地址,而不再进行拷贝操作,程序大同小异:
SECTION .data; Section containing initialised dataErrMsg db "Terminated with error.",10ERRLEN equ $-ErrMsgSECTION .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.; Argument lengths are stored in a table. Access arg lengths this way:;[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. MAXARGS equ 10; Maximum # of args we supportArgLens: resd MAXARGS; Table of argument lengthsSECTION .text; Section containing codeglobal _start; Linker needs this to find the entry point!_start:nop; This no-op keeps gdb happy...mov ebp,esp; Save the initial stack pointer in EBP; Copy the command line argument count from the stack and validate it:cmp dword [ebp],MAXARGS; See if the arg count exceeds MAXARGSja Error; If so, exit with an error message; Here we calculate argument lengths and store lengths in table ArgLens:xor eax,eax; Searching for 0, so clear AL to 0xor ebx,ebx; Stack address offset starts at 0ScanOne:mov ecx,0000ffffh; Limit search to 65535 bytes maxmov edi,dword [ebp+4+ebx*4] ; Put address of string to search in EDImov edx,edi; Copy starting address into EDX cld; Set search direction to up-memoryrepne scasb; Search for null (0 char) in string at edijnz Error; REPNE SCASB ended without finding ALmov byte [edi-1],10; Store an EOL where the null used to besub edi,edx; Subtract position of 0 from start addressmov dword [ArgLens+ebx*4],edi; Put length of arg into tableinc ebx; Add 1 to argument countercmp ebx,[ebp]; See if arg counter exceeds argument countjb ScanOne; If not, loop back and do another one; Display all arguments to stdout:xor esi,esi; Start (for table addressing reasons) at 0Showem:mov ecx,[ebp+4+esi*4]; Pass offset of the messagemov eax,4; Specify sys_write callmov ebx,1; Specify File Descriptor 1: Standard Outputmov edx,[ArgLens+esi*4]; Pass the length of the messageint 80H; Make kernel callinc esi; Increment the argument countercmp esi,[ebp]; See if we've displayed all the argumentsjb Showem; If not, loop back and do anotherjmp Exit; We're done! Let's pack it in!Error: mov eax,4; Specify sys_write callmov ebx,1; Specify File Descriptor 2: Standard Errormov ecx,ErrMsg; Pass offset of the error messagemov edx,ERRLEN; Pass the length of the messageint 80H; Make kernel callExit:mov eax,1; Code for Exit Syscallmov ebx,0; Return a code of zeroint 80H; Make kernel call
程序分析:
mov ebp,esp //ebp =esp,保存栈指针到ebp
cmp dword [ebp],MAXARGS //比较ebp保存的地址指向的内存的内容(命令行参数个数),与最大参数个数
ja Error //如果大于,跳转到Error
xor eax,eax //eax=0,al=0
xor ebx,ebx //ebx=0
ScanOne:
mov ecx,0000ffffh //ecx=65535
mov edi,dword [ebp+4+ebx*4] //edi = &ebp[ebx*4+4],命令行参数的首地址
mov edx,edi //edx=edi
cld //清除DF标志,内存地址变化方向从低到高
repne scasb //扫描字符串,如果遇到0,则结束。
jnz Error //如果循环结束,ZF标志位没有设置,则说明ecx=0,属于异常情况,跳转到Error
mov byte [edi-1],10 //字符串的结尾的0字符替换成10(换行符)
sub edi,edx //算出字符串长度,包括换行符
mov dword [ArgLens+ebx*4],edi //保存长度到数组中
inc ebx //ebx=ebx+1
cmp ebx,[ebp] //比较ebx和命令行参数个数
jb ScanOne //如果小于继续循环
xor esi,esi //esi=0
Showem:
mov ecx,[ebp+4+esi*4] //ecx=命令行参数字符串起始地址
mov eax,4
mov ebx,1
mov edx,[ArgLens+esi*4] //字符串长度
int 80H
inc esi //esi = esi +1
cmp esi,[ebp] //比较esi与命令行参数个数
jb Showem //小于继续循环
jmp Exit
测试:
[root@bogon showargs2]# makenasm -f elf -g -F stabs showargs2.asm -l showargs2.lstld -o showargs2 showargs2.o[root@bogon showargs2]# ./showargs2 p1 p2./showargs2p1p2
- 32位汇编语言学习笔记(38)--显示命令行参数(2)
- 32位汇编语言学习笔记(37)--显示命令行参数
- 32位汇编语言学习笔记(44)--显示命令行参数(3)
- 32位汇编语言学习笔记(35)--显示ASCII表
- 32位汇编语言学习笔记(39)--显示环境变量
- 32位汇编语言学习笔记(2)--数据传送指令
- 32位汇编语言学习笔记(23)--大小写转换程序2
- windows下32位汇编语言学习笔记
- windows下32位汇编语言学习笔记
- windows下32位汇编语言学习笔记
- 32位汇编语言学习笔记(18)--联合
- 32位汇编语言学习笔记(34)--一个数据的柱状图显示程序
- 32位汇编语言学习笔记(32)--loop指令
- 32位汇编语言学习笔记(1)--简单示例
- 32位汇编语言学习笔记(4)--移位操作
- 32位汇编语言学习笔记(5)--特殊的算术操作
- 32位汇编语言学习笔记(6)--设置条件码
- 32位汇编语言学习笔记(7)--跳转指令
- for(String file : filelist)如何理解?
- windows GDI编程窗口模板
- [Android] Android开发优化之——对界面UI的优化(2)
- SQL 基础用法语句
- objective-c 封装
- 32位汇编语言学习笔记(38)--显示命令行参数(2)
- C/C++的参数传递机制
- [Android] Android开发优化之——对界面UI的优化(3)
- 11.3 重构计算顺序
- 温度传感器Pt100 热电阻的原理
- android 使用webview
- 数据结构基础(17) --二叉查找树的设计与实现
- [Android] Android开发优化之——对Bitmap的内存优化
- BUG: OpenGL error 0x0500 in -[CCEAGLView swapBuffers] 328