I actually wanted to write a program in assembly(linux) , to accept filename from the command line and I was successful by retrieving the values from the stack using successive pop opcodes when I used "ld" command to build but I was unsuccessful when i used "gcc" command . I need to use gcc because I will be using various C std library function in this program.
Actually the file was creating , but its always got a "Invalid encoding " label and appeared like <? G ?
in the directory.I wanted to know:
- Do we follow a different procedure when built using gcc tools
- What was the possible reason for an invalid encoding file being created (out of curiosity).
Here is a sample code that works with ld but not with gcc.
section .data
filename: db 'testing',0
section .text
;extern printf ;to be uncommented when using gcc
;extern scanf ; -do-
global _start ; replace with main when using gcc
_start: ; replace with main:
pop ebx ; argc (argument count)
pop ebx ; argv[0] (argument 0, the program name)
pop ebx ; The first real arg, a filename
mov eax,8
; issue: ebx is not holding the filename popped from cli using gcc
;mov ebx,filename ; filename as a constant works with gcc but cli?
mov ecx,00644Q ; Read/write permissions in octal (rw_rw_rw_)
int 80h ; Call the kernel
; Now we have a file descriptor in eax
test eax,eax ; Lets make sure the file descriptor is valid
js terminate ; If the file descriptor has the sign flag
call fileWrite
terminate:
mov ebx,eax ; If there was an error, save the errno in ebx
mov eax,1 ; Put the exit syscall number in eax
int 80h ; control over to kernel
fileWrite: ; simply closing the file for time being
mov ebx,eax ; edited
mov eax,6 ; sys_close (ebx already contains file descriptor)
int 80h
call terminate
Solution and Caveat: There is a difference in the stack when using libc or bare-bone assembly.
When using libc the , the first pop returns the return address followed by argc and argv values respectively.
In bare-bone assembly , the first pop return the argc ,and every pop hence gives the successive argv values unlike a arguments pointer returned when using libc.
gcc
command when linking is just a frontend for theld
command, it still callsld
to do the actual linking, passing along the flags needed for the standard library. If you want to use the standard C library, just add the flag to link with it:-lc
. – Some programmer dude; sys_close (ebx already contains file descriptor)
. Does it? – Weather Vanegcc foo.o
actually usesld crt.o foo.o -lc
. You can usegcc -nostartfiles
to get libc but not the CRT startup code which defines_start
. See stackoverflow.com/questions/36861903/… – Peter Cordes