News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Tiny Linux example

Started by Gunther, September 03, 2010, 01:52:51 PM

Previous topic - Next topic

Gunther

Here is a small 32bit Linux example, entirely written in assembly language. The program writes a string into a file, which is created before. I've included the building and running commands as comments at the top of the source files. The application should run on any distribution (I used Ubuntu and Slackware). There are 2 source code versions, which lead to the same program: one for gas, the other for nasm.

Source file.s for gas:

/*
Build: as -o file.o file.s
       ld -o file file.o
Run:   ./file file.txt
*/

.equ SYSCALL,0x80
.equ sys_exit,1
.equ sys_write,4
.equ sys_close,6
.equ sys_create,8
.equ rw_permission,0x1a4

.globl _start

.section .data

string: .ascii "This simple string will be written into a file.\n"
string_end: .set stringlen, string_end - string

.section .text

_start:

popl %edi #argument count
popl %esi #argv[0] = program name
popl %ebx #filename
movl $sys_create,%eax #create file
#ebx has filename
movl $rw_permission,%ecx #file is readable/writeable
int $SYSCALL #transfer to kernel

#Check for a valid file descriptor

test %eax,%eax #file descriptor positive?
js 1 #no: jump (error)
call WriteFile #yes: write into the file

1:

movl %eax,%ebx #save error number
movl $sys_exit,%eax #terminate
int $SYSCALL #transfer to kernel

#Purpose: Write a string into a file.
#Input: eax = file descriptor
WriteFile:

movl %eax,%ebx #save file descriptor
movl $sys_write,%eax #write into file
movl $string,%ecx #ecx -> write buffer
movl $stringlen,%edx #edx = # bytes (string length)
int $SYSCALL #transfer to kernel
movl $sys_close,%eax #close file
int $SYSCALL #transfer to kernel
ret



Source file.asm for nasm:

;Build: nasm -f elf -o file.o file.asm
;       ld -o file file.o
;Run:   ./file file.txt

BITS 32

%define SYSCALL 80h
%define lf 0ah
%define sys_exit 1
%define sys_write 4
%define sys_close 6
%define sys_create 8
%define rw_permission 00644Q ;octal number

global _start

section .data

string db 'This simple string will be written into a file.',lf
stringlen equ $ - string

section .text

_start:

pop edi ;argument count
pop esi ;argv[0] = program name
pop ebx ;filename
mov eax,sys_create ;create file
;ebx has filename
mov ecx,rw_permission ;file is readable/writeable
int SYSCALL ;transfer to kernel

;Check for a valid file descriptor

test eax,eax ;file descriptor positive?
js .skipWriting ;no: jump (error)
call WriteFile ;yes: write into the file

.skipWriting:

mov ebx,eax ;save error number
mov eax,sys_exit ;terminate
int SYSCALL ;transfer to kernel

;Purpose: Write a string into a file.
;Input: eax = file descriptor
WriteFile:

mov ebx,eax ;save file descriptor
mov eax,sys_write ;write into file
mov ecx,string ;ecx -> write buffer
mov edx,stringlen ;edx = # bytes (string length)
int SYSCALL ;transfer to kernel
mov eax,sys_close ;close file
int SYSCALL ;transfer to kernel
ret



Gunther
Forgive your enemies, but never forget their names.

Twister


Gunther

Quote from: GTX September 03, 2010, 11:31:33 pm@Lol, AT&T syntax.

And nasm syntax, too.

Gunther
Forgive your enemies, but never forget their names.

MichaelW

Does the Intel assembler syntax (for example .intel_syntax noprefix) work under Linux?
eschew obfuscation

Vortex

Hi Gunther,

It's a matter of personal preference but you should prefer the Intel syntax. pop esi looks much more better than popl %esi Why to type the extra characters l and % ?

jcfuller

Quote from: MichaelW on September 04, 2010, 08:02:43 AM
Does the Intel assembler syntax (for example .intel_syntax noprefix) work under Linux?

It does with JWASM  :bg

James

BogdanOntanu

Here is a tiny example in Sol_ASM syntax ;)
Works on any Linux/Unix version that has a libC available to link.


;------------------------------------------------------------------------
; Solar Assembler example of making ELF32 object file
;
; build with:
; sol_asm2 test.asm test.obj -elf32
;
; link with:
; gcc test.obj -o test.exe
;
; run:
; ./test.exe
;-----------------------------------------------------------------------
section ".text" class_code
section ".data" class_data

;-----------------------
; functions from libC
;-----------------------
extern puts cdecl
extern exit cdecl
extern printf cdecl

.entry main

..data
msg_01 db 13,10,'Hi from Sol_Asm LIBC sample',0
msg_02 db 13,10,'Message number 02',0
msg_fmt db 13,10,'Printf message: number1=%x main=%x ',13,10,0
..text

main:
;-------------------------------
; use libc puts to write strings
;-------------------------------
invoke puts,msg_01

invoke puts,msg_02

;-----------------------
; use libc printf
;-----------------------
invoke printf, msg_fmt,777h,main

;------------------------
; libC exit function
;------------------------
invoke exit,77h

ret

;-----------------------------
; the end of this programm
;-----------------------------

Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro

Gunther

Quote from: MichaelW September 04, 2010, at 09:02:43 AMDoes the Intel assembler syntax (for example .intel_syntax noprefix) work under Linux?

Yes, it works.
Source for gas in Intel syntax:

/*
Build: as -o file.o file.s
       ld -o file file.o
Run:   ./file file.txt
*/

.equ SYSCALL,0x80
.equ sys_exit,1
.equ sys_write,4
.equ sys_close,6
.equ sys_create,8
.equ rw_permission,0x1a4

.globl _start

.section .data

string: .ascii "This simple string will be written into a file.\n"
string_end: .set stringlen, string_end - string

.section .text

_start:

.intel_syntax noprefix #switch to Intel syntax

pop edi #argument count
pop esi #argv[0] = program name
pop ebx #filename
mov eax,sys_create #create file
#ebx has filename
mov ecx,rw_permission #file is readable/writeable
int SYSCALL #transfer to kernel

#Check for a valid file descriptor

test eax,eax #file descriptor positive?
js 1f #no: jump (error)
call WriteFile #yes: write into the file

1:

mov ebx,eax #save error number
mov eax,sys_exit #terminate
int SYSCALL #transfer to kernel

#Purpose: Write a string into a file.
#Input: eax = file descriptor
WriteFile:

mov ebx,eax #save file descriptor
mov eax,sys_write #write into file
mov ecx,offset string #ecx -> write buffer
mov edx,stringlen #edx = # bytes (string length)
int SYSCALL #transfer to kernel
mov eax,sys_close #close file
int SYSCALL #transfer to kernel
ret



But that source line switch doesn't work under Intel based Mac OS X. The Apple people patched the switch away, so you have to use AT&T syntax and nothing else.

Gunther

Forgive your enemies, but never forget their names.

Gunther

Quote from: Vortex September 04, 2010, at 09:58:18 AMIt's a matter of personal preference but you should prefer the Intel syntax. pop esi looks much more better than popl %esi Why to type the extra characters l and % ?

Yes, it is a matter of taste. I don't prefer any syntax. In some points the AT&T syntax is much more clear as the Intel syntax. The extra characters occur with Intel syntax, too. For example: the hole bunch of offset, dword ptr, qword ptr etc. which isn't necessary with AT&T syntax. All together lead both syntaxes to the same machine language representation. It's a definitive advantage to be at home in both worlds.

But it's clear: there are much more Intel syntax sources available via the net. AT&T sources are rare birds.

Gunther
Forgive your enemies, but never forget their names.