Author Topic: Linux 64bit / Threads  (Read 1062 times)

Offline andyz74

  • Jr. Member
  • *
  • Posts: 15
Linux 64bit / Threads
« on: January 24, 2024, 05:38:14 PM »
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: [Select]
; 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


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 :-)

Offline fredericopissarra

  • Full Member
  • **
  • Posts: 368
  • Country: br
Re: Linux 64bit / Threads
« Reply #1 on: January 25, 2024, 08:48:30 AM »
There are no 'threads' here, but different processes...
Here's a better implementation for your forking...

Code: [Select]
; 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
« Last Edit: January 25, 2024, 09:19:29 AM by fredericopissarra »

Offline andyz74

  • Jr. Member
  • *
  • Posts: 15
Re: Linux 64bit / Threads
« Reply #2 on: January 25, 2024, 08:31:24 PM »
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.

Offline fredericopissarra

  • Full Member
  • **
  • Posts: 368
  • Country: br
Re: Linux 64bit / Threads
« Reply #3 on: January 26, 2024, 12:09:53 PM »
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)...

Offline andyz74

  • Jr. Member
  • *
  • Posts: 15
Re: Linux 64bit / Threads
« Reply #4 on: January 30, 2024, 06:54:30 PM »
OK, so I will see, if I can get a working program of this. :-)

Thanks for the hint! :-)