initial import
[staff/goc4/2018bti7061.git] / asm-8-strings / examples / showargs / showargs64.asm
1 ; Executable name : showargs64
2 ; Version : 1.0
3 ; Created date : 10/11/2014
4 ; Last update : 10/11/2014
5 ; Author : Emmanuel Benoist
6 ; Description : A program for showing command line arguments
7 ; on 64-bit
8 ;;;
9 ;;; MAJOR Change with the original program
10 ;;; The args are not in stack, but refered to in stack once
11 ;;;
12 ; Build using these commands:
13 ; nasm -f elf64 -g -F stabs showargs64.asm
14 ; ld -o showargs showargs64.o
15 ;
16
17 SECTION .data ; Section containing initialised data
18
19 ErrMsg db "Terminated with error.",10
20 ERRLEN equ $-ErrMsg
21
22 SECTION .bss ; Section containing uninitialized data
23
24 ; This program handles up to MAXARGS command-line arguments. Change the
25 ; value of MAXARGS if you need to handle more arguments than the default 10.
26 ; In essence we store pointers to the arguments in a 0-based array, with the
27 ; first arg pointer at array element 0, the second at array element 1, etc.
28 ; Ditto the arg lengths. Access the args and their lengths this way:
29 ; Arg strings: [ArgPtrs + <index reg>*8]
30 ; Arg string lengths: [ArgLens + <index reg>*8]
31 ; Note that when the argument lengths are calculated, an EOL char (10h) is
32 ; stored into each string where the terminating null was originally. This
33 ; makes it easy to print out an argument using sys_write. This is not
34 ; essential, and if you prefer to retain the 0-termination in the arguments,
35 ; you can comment out those lines as indicated.
36
37 MAXARGS equ 10 ; Maximum # of args we support
38 ArgCount: resq 1 ; # of arguments passed to program
39 ArgPtrs: resq MAXARGS ; Table of pointers to arguments
40 ArgLens: resq MAXARGS ; Table of argument lengths
41
42 SECTION .text ; Section containing code
43
44 global _start ; Linker needs this to find the entry point!
45
46 _start:
47 nop ; This no-op keeps gdb happy...
48
49
50 ; Get the command line argument count off the stack and validate it:
51 pop r12 ; TOS contains the argument count
52 cmp r12,MAXARGS ; See if the arg count exceeds MAXARGS
53 ja Error ; If so, exit with an error message
54 mov qword [ArgCount],r12 ; Save arg count in memory variable
55
56 pop rdi ; Read the start of all strings
57 xor rbx,rbx ; Counts the number of strings (<=[ArgCount])
58
59
60 ScanOne:
61 mov [ArgPtrs + rbx*8],rdi ; Save the pointer into Array
62 mov rcx,0000ffffh ; Limit search to 65535 bytes max
63 mov rdx,rdi ; Copy starting address into EDX
64 cld ; Set search direction to up-memory
65 repne scasb ; Search for null (0 char) in string at edi
66 mov byte [rdi-1],10 ; Store an EOL where the null used to be
67 mov r8,rdi
68 sub r8,rdx ; Subtract position of 0 from start address
69 mov qword [ArgLens+rbx*8],r8 ; Put length of arg into table
70 inc rbx ; Add 1 to argument counter
71 cmp rbx,[ArgCount] ; See if arg counter exceeds argument count
72 jb ScanOne ; If not, loop back and do another one
73
74
75
76
77 ; Display all arguments to stdout:
78 xor r13,r13 ; Start (for table addressing reasons) at 0
79
80 Showem:
81 mov rax,1 ; Specify sys_write call
82 mov rdi,1
83 mov rsi,[ArgPtrs+r13*8] ; Pass offset of the message
84 mov rdx,[ArgLens+r13*8] ; Pass the length of the message
85 syscall ; Make kernel call
86 inc r13 ; Increment the argument counter
87 cmp r13,[ArgCount] ; See if we've displayed all the arguments
88 jb Showem ; If not, loop back and do another
89 jmp Exit ; We're done! Let's pack it in!
90
91
92 Error: mov eax,4 ; Specify sys_write call
93 mov ebx,1 ; Specify File Descriptor 2: Standard Error
94 mov ecx,ErrMsg ; Pass offset of the error message
95 mov edx,ERRLEN ; Pass the length of the message
96 int 80H ; Make kernel call
97
98 Exit: mov rax,1 ; Code for Exit Syscall
99 mov rbx,0 ; Return a code of zero
100 int 80H ; Make kernel call