flat assembler
Message board for the users of flat assembler.

Index > Linux > pie pic

Author
Thread Post new topic Reply to topic
mikado3333



Joined: 31 Oct 2015
Posts: 12
Location: Russian Federation
mikado3333 04 Jan 2026, 09:29
Hello! Please tell me how to implement the following code written in NASM on FASM(https://metanit.com/assembler/nasm/10.2.php).

Code:
global print:function
 
extern message  ; импортируем строку для вывода
extern count    ; импортируем размер строки
 
; Функция print выводит текст на консоль
section .text
print:
    mov rsi, [rel message wrt ..got]    ; загружаем адрес message из GOT
    mov rdx, [rel count wrt ..got]      ; загружаем адрес count из GOT
    mov rdx, [rdx]                      ; загружаем значение count по вышезагруженному адресу
    mov rdi, 1
    mov rax, 1
    syscall
    ret
    

Code:
global _start   
 
global message:data
global count:data
   
extern print
  
section .data 
count: dq message.end - message
message: db "Hello METANIT.COM!",10, 0
.end:
 
section .text
_start:
    call print wrt ..plt
    mov rax, 60    
    syscall
    
Post 04 Jan 2026, 09:29
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1205
Location: Russia
macomics 04 Jan 2026, 12:34
As single file:
Code:
; fasm -m 10240 ./single.asm ./single && ./single
format ELF64 executable 3
segment executable
entry $

; copy from NASM source
    call print; wrt ..plt
    mov rax, 60    
    syscall

; copy from NASM source
print:
;    mov rsi, [rel message wrt ..got]    ; загружаем адрес message из GOT
    lea rsi, [message]
;    mov rdx, [rel count wrt ..got]      ; загружаем адрес count из GOT
    lea rdx, [count]
    mov rdx, [rdx]                      ; загружаем значение count по вышезагруженному адресу
    mov rdi, 1
    mov rax, 1
    syscall
    ret

segment readable
; copy from NASM source
count: dq message.end - message
message: db "Hello METANIT.COM!",10, 0
.end:    


As separate linkable ELF files
Code:
; fasm -m 10240 ./print.asm ./print.o
format ELF64
public print
extrn count
extrn message
section ".text" executable

; copy from NASM source
print:
;    mov rsi, [rel message wrt ..got]    ; загружаем адрес message из GOT
    lea rsi, [message]
;    mov rdx, [rel count wrt ..got]      ; загружаем адрес count из GOT
    lea rdx, [count]
    mov rdx, [rdx]                      ; загружаем значение count по вышезагруженному адресу
    mov rdi, 1
    mov rax, 1
    syscall
    ret    
Code:
; fasm -m 10240 ./start.asm ./start.o
format ELF64

public _start
public count
public message
extrn print

; copy from NASM source
section ".data" writeable
count: dq message.end - message
message: db "Hello METANIT.COM!",10, 0
.end:

section ".text" executable
_start:

; copy from NASM source
    call print; wrt ..plt
    mov rax, 60
    syscall    

Linking...
Code:
ld -o ./linkable ./start.o ./print.o && ./linkable    


https://flatassembler.net/fasm-1.73.34.tar.gz

ADD: If you need a table for addressing beyond 2GB (GOT - global offset table), then you need to create it yourself.
Post 04 Jan 2026, 12:34
View user's profile Send private message Reply with quote
mikado3333



Joined: 31 Oct 2015
Posts: 12
Location: Russian Federation
mikado3333 04 Jan 2026, 14:25
Thanks, macomics. But I need to build it like in the manual example.https://metanit.com/assembler/nasm/10.2.php
Code:
root@Eugene:~/asm# nasm -felf64 print.asm -o print.o
root@Eugene:~/asm# ld -shared print.o -o print.so
root@Eugene:~/asm# nasm -felf64 app.asm -o app.o
root@Eugene:~/asm# ld --dynamic-linker=/lib64/ld-linux-x86-64.so.2 [color=red]-pie[/color] app.o print.so -o app
root@Eugene:~/asm# export LD_LIBRARY_PATH=.
root@Eugene:~/asm# ./app
Hello World!
root@Eugene:~/asm# 
    


Is there a manual for FASM on this topic?

when I try to build a library (lib.so) from this code
Code:
; fasm -m 10240 ./print.asm ./print.o
format ELF64
public print
extrn count
extrn message
section ".text" executable

; copy from NASM source
print:
;    mov rsi, [rel message wrt ..got]    ; загружаем адрес message из GOT
    lea rsi, [message]
;    mov rdx, [rel count wrt ..got]      ; загружаем адрес count из GOT
    lea rdx, [count]
    mov rdx, [rdx]                      ; загружаем значение count по вышезагруженному адресу
    mov rdi, 1
    mov rax, 1
    syscall
    ret   
     


ld -shared t2.o -o t2.so
ld: t2.o: предупреждение: перемещение указывает на «message» из раздела только для чтения «.text»
ld: t2.o: перемещение R_X86_64_PC32 для не определено символ «message» не может использоваться при создании общий объект; перекомпилируйте с параметром -fPIC
ld: ошибка конечной ссылки: некорректное значение
Post 04 Jan 2026, 14:25
View user's profile Send private message Reply with quote
mikado3333



Joined: 31 Oct 2015
Posts: 12
Location: Russian Federation
mikado3333 04 Jan 2026, 15:59
Based on this topic https://board.flatassembler.net/topic.php?t=4964&postdays=0&postorder=asc&start=20,
calling functions from the application is done via "call plt function",
but it is still unclear how to wrap external variables in the library in PIC
Post 04 Jan 2026, 15:59
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1205
Location: Russia
macomics 04 Jan 2026, 17:04
Alternatively, you can do this
Code:
; fasm -m 10240 ./print.asm ./print.o
; ld -shared -o /tmp/print.so ./print.o
format ELF64
section ".text" executable
extrn count
extrn message

; copy from NASM source
print:
public print
    call plt message      ; загружаем адрес message из GOT
    mov rsi, rax
    call plt count        ; загружаем адрес count из GOT
    mov rdx, rax
    mov rdx, [rdx]        ; загружаем значение count по вышезагруженному адресу
    mov rdi, 1
    mov rax, 1
    syscall
    ret    
Code:
; fasm -m 10240 ./start.asm ./start.o
; ld --dynamic-linker=/lib64/ld-linux-x86-64.so.2 -pie ./start.o /tmp/print.so -o ./start && ./start
format ELF64

section ".data" writeable
_count: dq _message.end - _message
_message: db "Hello METANIT.COM!",10, 0
.end:

section ".text" executable

extrn print
_start:
public _start
    call plt print
    mov rax, 60
    syscall

message:
public message
    lea rax, [_message]
    retn

count:
public count
    lea rax, [_count]
    retn    
Code:
$ fasm -m 10240 ./print.asm ./print.o
flat assembler  version 1.73.32  (10240 kilobytes memory, x64)
1 passes, 640 bytes.
$ ld -shared -o /tmp/print.so ./print.o
$ fasm -m 10240 ./start.asm ./start.o
flat assembler  version 1.73.32  (10240 kilobytes memory, x64)
2 passes, 816 bytes.
$ ld --dynamic-linker=/lib64/ld-linux-x86-64.so.2 -pie ./start.o /tmp/print.so -o ./start && ./start
Hello METANIT.COM!
    
But it's still a crutch using plt, and you should create a GOT and use offsets in it. GOT is just an array of all the pointers inside the module. A pointer to GOT can be passed through this crutch to the module.
Post 04 Jan 2026, 17:04
View user's profile Send private message Reply with quote
mikado3333



Joined: 31 Oct 2015
Posts: 12
Location: Russian Federation
mikado3333 04 Jan 2026, 17:39
Please show me an example of creating a table GOT.
Post 04 Jan 2026, 17:39
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1205
Location: Russia
macomics 04 Jan 2026, 17:46
Code:
; ./start.asm
GOT:
.count   dq count   ; index=0, offset=0
.message dq message ; index=1, offset=8    
Post 04 Jan 2026, 17:46
View user's profile Send private message Reply with quote
mikado3333



Joined: 31 Oct 2015
Posts: 12
Location: Russian Federation
mikado3333 05 Jan 2026, 00:37
result. I don't know how correct it is, but it works (Thank you very much macomics).

Code:
format ELF64

public print

extrn message  ; Импортируем строку
extrn count    ; Импортируем размер

section '.text' executable

print:
    mov rsi, [message_got]    ; Загружаем адрес message из GOT через локальную метку
    mov rdx, [count_got]      ; Загружаем адрес count из GOT
    mov rdx, [rdx]            ; Загружаем значение count
    mov rdi, 1
    mov rax, 1
    syscall
    ret

; Секция .got: placeholders для линкера, чтобы создать GOT-entries для extern символов
section '.got'
message_got: dq message  
count_got:   dq count 
    


Code:
format ELF64

public _start
public count
public message
extrn print


section ".data" writeable
count: dq message.end - message
message: db "Hello METANIT.COM!",10, 0
.end:

section ".text" executable

_start:

    call PLT print
    mov rax, 60
    syscall  
    


Two questions remain:
1- fasm uses "RIP-relative addressing" for the command "mov"?
2- Is it possible to do without an operator "PLT"?
Post 05 Jan 2026, 00:37
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.