Rambler's
Top100

Три примера использования GNU Assembler (GAS)

Автор: lonesome TSH/Digital Daemons
Дата: 17.04.2003
Раздел: Низкоуровневое программирование в Linux

Пример номер 0: Hello Linux

#Файл sample1.s

.globl _start #Метка _start - глобальная
              #Она необходима компоновщику для определения точки входа

.code32      #Директива определяющая разрядность
.text         #Сегмент кода
_start:       #Точка входа

movl $4, %eax
movl $1, %ebx
movl $message, %ecx
movl $mlen, %edx
int $0x80     #write (4, 1, message, mlen)

movl $1, %eax
xorl %ebx, %ebx
int $0x80     #exit(0) 

.data         #Сегмент данных
message: .asciz "Hello Linux\n" #asciz - последовательность байт,
                                # заканчивающаяся нулем
# (C-строка)

mlen = .-message#Констнта mlen
Компиляция: as sample0.s -o sample0.o
Компоновка: ld sample0.o -o sample0

Пример номер 1: Используем стандартный загрузчик GLIBC

Действительно, зачем создавать функцию _start самому, когда она уже есть в GLIBC?

.globl main      #Основная функция программы с точки зрения GLIBC - main

.text
main:            #На нее GLIBC и передаст управление


movl $11, %eax #11 - номер системного вызова execve
movl $program, %ebx
movl $null, %ecx
movl $null, %edx
int $0x80        #execve (program, null, null)
         #execve не возвращается в случае успешного вызова
 #весь код программы будет переписан кодом вызванной программы

.data
program: .asciz "/bin/date"     #Запускаемая программа
null:.long 0  #Указатель на NULL

Обратите внимание на отличие компиляции если мы используем GLIBC:

gcc sample1.s -o sample1 - как видите, всю черную работу по подключению необходимых библиотек мы оставили GCC

Пример номер 2: Взаимодействуем с GLIBC

Действительно, зачем генерировать прерывание системного вызова самому, когда это можно предоставить GLIBC?

.globl main
.globl printf

.text
main:
pushl $message3
pushl $message2
pushl $message1
pushl $message
call printf     #printf(message, message1, message2, message3)
addl $16, %esp  #А стек по конвенции C необходимо восстановить
                #Мы ведь клали в него 4 аргумента по 4 байта каждый
ret

.data
message:.asciz "It is not so easy %s %s %s"
message1:.asciz "to write"
message2:.asciz "printf in assembly."
message3:.asciz "Better use glibc's printf\n"


Rambler's Top100