NASM Forum > Programming with NASM
Linux 64bit / Threads
(1/1)
andyz74:
Hi !
I'm just playing around with learning about threads. Somewhere in the internet I found a little example and changed it for my mind and it seems to work correct for now.
--- Code: ---; Fork
; nasm -f elf64
; ld fork.o -o fork
; Run with: ./fork
[bits 64]
SECTION .data
childMsg db 'This is the child process', 0h ; a message string
clength equ $-childMsg
parentMsg db 'This is the parent process', 0h ; a message string
plength equ $-parentMsg
crlf db 0xA,0xD ; newline, length is 2
SECTION .text
global _start
_start:
mov rax, 57 ; SYS_FORK
syscall
cmp rax, 0 ; if eax is zero we are in the child process
jz child ; jump if eax is zero to child label
parent:
mov rax, 1 ; sys_write
mov rdi, 1 ; stdout
mov rsi, parentMsg ; message address
mov rdx, plength ; message string length
syscall
mov rax, 1 ; sys_write
mov rdi, 1 ; stdout
mov rsi, crlf ; message address
mov rdx, 2 ; message string length
syscall
call workalot
jmp exit
child:
mov rax, 1 ; sys_write
mov rdi, 1 ; stdout
mov rsi, childMsg ; message address
mov rdx, clength ; message string length
syscall
mov rax, 1 ; sys_write
mov rdi, 1 ; stdout
mov rsi, crlf ; message address
mov rdx, 2 ; message string length
syscall
call workalot
jmp exit
exit:
mov rax, 60 ; sys_exit
mov rdi, 0 ; return 0 (success)
syscall
; -------- unten nur proceduren ---------------------
workalot:
mov rcx, 65000
loop1:
push rcx
mov rcx, 65000
loop2:
push rcx
nop
pop rcx
loop loop2
pop rcx
loop loop1
ret
--- End code ---
As you see, it just throws out two little messages in a fork and runs down a delay and stops.
Now, my question is, if I have dependencies in the threads at each other, maybe some calculations with needed sums at the end, than I have to wait for this.
I know, there exists something called
"SYSCALL_WAIT4"
but to be honest, I don't have a clue, how to realize that. :-/
Does anyone habe a nice example or can explain a little bit?
Greetings, Andy :-)
fredericopissarra:
There are no 'threads' here, but different processes...
Here's a better implementation for your forking...
--- Code: ---; fork,asn
;
; nasm -f elf64 -o fork.o fork.asm
; ld -s fork.o -o fork
; ./fork
bits 64
default rel ; All offset only effective addresses are rip-relative from now on...
; Since no data will be writen, they can be at .rodata section.
section .rodata
; We don't need the nul char!
childMsg db `This is the child process\n` ; a message string
clength equ $-childMsg
parentMsg db `This is the parent process\n` ; a message string
plength equ $-parentMsg
tspec:
dq 3 ; 3 seconds delay.
dq 0
section .text
global _start
_start:
; Notice: Using RAX here will encode a 10 bytes instruction (rex prefix, 8 bytes for the immediate and the opcode).
; In x86-64 mode, changing E?? will AUTOMATICALLY zero the upper 32 bits of R?? registers.
mov eax,57 ; sys_fork
syscall
; fork() will return a file descriptor (int type).
test eax,eax
js .fail ; sys_fork can fail (returs a descriptor < 0).
jz .child
; Parent process.
mov eax,1 ; sys_write
mov edi,eax ; stdout
lea rsi,[parentMsg] ; Must be rip-relative addressing.
mov edx,plength
syscall
call workalot
.exit:
mov eax,60
xor edi,edi
syscall
.fail:
mov eax,60
mov edi,1
syscall
align 4
.child:
mov eax,1 ; sys_write
mov edi,eax ; stdout
lea rsi,[childMsg] ; message address (rip-relative)
mov edx,clength ; message string length
syscall
call workalot
jmp .exit
; -------- unten nur proceduren ---------------------
align 4
workalot:
mov eax,35 ; sys_nanosleep
lea rdi,[tspec]
xor esi,esi
syscall
ret
--- End code ---
andyz74:
OK, I've tested your code and it runs nicely. :-)
But to be honest, I think, my intended question is still open. (Waiting at each other of the processes...)
Maybe I should explain a little better : I have modified this code to calculate primes. Let's say, i want to test the number 2000 to be a prime:
So I divided 2000 by 2 ( got 1000 ) and
tell the parent process to divide the 2000 through all numbers between 2 and 1000, and
tell the child process to divide the 2000 through all numbers between 1000 and 2000.
I know, the range can easily be decreased from 2 to sqrt(number) but I do it like this for testing the fork-thing.
If the parent-process, or the child-process sees a division which goes out even, some boolean-like variable like "not_a_prime" should be set to 1 and both processes could be stopped. Otherwise it is a prime.
fredericopissarra:
For a parent process to wait for a child one is a matter of using sys_wait4 syscall. You can retrieve the errorcode returned by the process (for example: 0 = prime, 1 = not prime)...
andyz74:
OK, so I will see, if I can get a working program of this. :-)
Thanks for the hint! :-)
Navigation
[0] Message Index
Go to full version