Author Topic: Segment Default on linking elf64  (Read 8922 times)

Offline Ferran

  • Jr. Member
  • *
  • Posts: 23
  • Country: ad
Segment Default on linking elf64
« on: August 19, 2020, 11:07:58 AM »
Hello everybody:

I'm still a newbie learning the assembly code. I'm trying to compile, linking and execute an script from capter 9.4 on assembly64.pdf but i can't.

the program named array4.asm is this:

Code: [Select]
; ***********************************************************************************
; array4.asm
; Exemple to learn how to use the stack to reverse a list of quadwords in
;place.
; Compile with nasm -f elf64 array4.asm
; Link with ld -o array4 array4.o
; Run with ./array4
;
; Source: assembly64.pdf (version 1.1.40)
; Author: Ed Jorgensen Ph.D.
; ************************************************************************************
section .data
    lst dq 121, 122, 123, 124, 125
    len dq 5
; ************************************************************************************
section .text
global _start

_start:

; loop to put the numbers on stack

    mov rcx, qword len
    mov rbx, lst
    mov r12, 0
    mov rax, 0

pushloop:
   
    push qword [rbx+r12*8]
    inc r12
    loop pushloop

; ----
; All numbers are on stack (in reverse order).
; Look to get them back off. Put them back into
; the original list...

    mov rcx, qword [len]
    mov rbx, lst
    mov r12, 0

 poploop:

    pop rax
    mov qword [rbx+r12*8], rax
    inc r12
    loop poploop

; ----
; Done. Terminate program.

exit:

    mov     rax, 60
    mov     rdi, 0
    syscall


Compiled with nasm -f elf64 array4.asm
Linked with ld  -o array4 array4.o
Executing with ./array4

But when I tries to link the object file the system shows a segment error of memory, but I'm not able to locate the problem so I need help to fix it. I hope you can.

Thank you in advance.
« Last Edit: August 19, 2020, 11:12:26 AM by Ferran »

Offline fredericopissarra

  • Full Member
  • **
  • Posts: 368
  • Country: br
Re: Segment Default on linking elf64
« Reply #1 on: August 19, 2020, 02:09:07 PM »
This is where the error is:
Code: [Select]
   mov rcx, qword len
But I recomend the following modifications (See NOTE: at comments):
Code: [Select]
; ***********************************************************************************
; array5.asm
; Exemple to learn how to use the stack to reverse a list of quadwords in place.
; Compile with nasm -f elf64 array4.asm
; Link with ld -o array4 array4.o
; Run with ./array4
;
; Source: assembly64.pdf (verdion 1.1.40)
; Author: Ed Jorgensen Ph.D.
; ************************************************************************************
    section .data

lst:  dq 121, 122, 123, 124, 125

; NOTE: Don't need to allocate memory to store lst array length.
len equ (($ - lst) / 8)

; ************************************************************************************
    section .text

    global _start
_start:

; loop to put the numbers on stack
;
; NOTE: When you're dealing with values less than 2³² you can use
;       the lower 32 bits portion of R?? register. The upper 32 will be
;       automaticaly zeroed.
;       I prefeer to load effective addresses with LEA, instead of MOV.
;       To zero a register, XOR is preferable (smaller instruction).
    mov ecx, len
    lea rbx, [lst]
    mov rdx, rbx      ; We'll use RDX below.
    xor edi,edi       ; Using EDI instead or R12 to create smaller instructions.
    xor eax,eax

; NOTE: Prefeer NOT to use INC/DEC and LOOP. Use ADD/SUB and DEC ECX/JNZ, instead.
;       They are faster.
;       Use 'local' labels if you don't intend to export them to the linker.
.pushloop:
    push qword [rbx+rdi*8]
    add rdi,1
    dec ecx
    jnz .pushloop

; ----
; All numbers are on stack (in reverse order).
; Look to get them back off. Put them back into
; the original list...
    mov ecx, len
    xor edi, edi

.poploop:
    pop rax
    mov [rdx+rdi*8], rax    ; NOTE: Using RDX insead of RBX here.
    add rdi,1
    dec ecx
    jnz .poploop

; ----
; Done. Terminate program.
    mov     eax, 60
    xor     edi,edi
    syscall

Offline Ferran

  • Jr. Member
  • *
  • Posts: 23
  • Country: ad
Re: Segment Default on linking elf64
« Reply #2 on: August 19, 2020, 06:44:18 PM »
@federicopissarra it works fine ! No more segment fault.

Another related question: How I can to print the current array's values ?

I tried this

Code: [Select]

.poploop:
    pop rax
    mov [rdx+rdi*8], rax    ; NOTE: Using RDX insead of RBX here.

    ;Here we should print the current array value:

    mov rdx, len                    ; Lenght of de value
    mov rcx, [rdx+rdi*8]        ; Let's put the current array value into buffer
    mov rbx, 1                       ; 1 = stdout
    mov rax, 1                       ; 1 = sys_write system call

    add rdi,1
    dec ecx
    jnz .poploop


Certanly, my idea don't works. What can i do there ?

Offline fredericopissarra

  • Full Member
  • **
  • Posts: 368
  • Country: br
Re: Segment Default on linking elf64
« Reply #3 on: August 20, 2020, 10:32:49 AM »
Another related question: How I can to print the current array's values ?
You'll need to implement something like this, in asm:
Code: [Select]
#include <stdlib.h>

void printvalue( long long v )
{
  int sign;
  char buffer[24];
  unsigned int size;
  char *p;

  sign = v < 0;

  size = 0;
  p = buffer + sizeof buffer - 1;

  do
  {
    *p-- = abs( v % 10 ) + '0';
    v /= 10;
    size++;
  } while ( v );

  if ( sign )
  {
    *p-- = '-';
    size++;
  }

  ++p;

  sys_write( 1, p, size );
}

Offline Ferran

  • Jr. Member
  • *
  • Posts: 23
  • Country: ad
Re: Segment Default on linking elf64
« Reply #4 on: August 20, 2020, 10:52:52 AM »
Not easy for me to implement with asm this... but i'll try it.

Thank you very much for your help.

Offline Ferran

  • Jr. Member
  • *
  • Posts: 23
  • Country: ad
Re: Segment Default on linking elf64
« Reply #5 on: August 21, 2020, 07:17:30 AM »
@federicopissarra

I search a possible solution to print the values but i blundered trying to implement it into the program. I decided to call printf imiplemented for ubuntu / linux mint (my distribution).

first I declaring the external command at the top of program

Code: [Select]
extern printf

and after we call printf with its arguments (values of the array) while the loop gets out them.

Code: [Select]
; ----
; All numbers are on stack (in reverse order).
; Look to get them back off. Put them back into
; the original list...

    mov ecx, len
    xor edi, edi

.poploop:
    pop rax
    mov [rdx+rdi*8], rax

; ----------- fix this -----------
   
    lea rsi, [rdx+rdi*8]
    call printf wrt ..plt

;---------------------------------
   
    add rdi,1
    dec ecx
    jnz .poploop


Surely it is necessary to give as an argument the format or length of the array but I do not know for sure. Also: I'm making a mess with the records and I don't know which one is useful to print the values.

I'm absolutely disoriented right now...

PD. Now we need to compile the program with nasm -f elf prog4.asm and link with gcc -no-pie progr4.o -o prog4

« Last Edit: August 21, 2020, 07:23:25 AM by Ferran »

Offline fredericopissarra

  • Full Member
  • **
  • Posts: 368
  • Country: br
Re: Segment Default on linking elf64
« Reply #6 on: August 21, 2020, 03:50:58 PM »
If you are willing to use an external funcion defined in the C Standard Library, which will link all inicialization/finalization code necessary, why bother to use assembly?

Offline Ferran

  • Jr. Member
  • *
  • Posts: 23
  • Country: ad
Re: Segment Default on linking elf64
« Reply #7 on: August 22, 2020, 08:19:33 AM »
@federicopissarra : I wanted see if the console shows the array values, either its way...


Well... i'm blocked, i'm tired and i'm bored.

Finally i left below the last modification trying to print the values of the array. The famous fault words appears again 'Segment faults', etc.
 
Code: [Select]
; ***********************************************************************************
; array4.asm
; Exemple to learn how to use the stack to reverse a list of quadwords in place.
; (it was modified to display the values on console)
; Compile with nasm -f elf64 array4.asm
; Link with ld -o array4 array4.o
; Run with ./array4
;
; Source: assembly64.pdf (ver. 1.1.40)
; Author: Ed Jorgensen Ph.D.
; (Modified by the NASM Forum members - forum.nasm.us)
;
; ************************************************************************************

    section .data

lst:  dq 121, 122, 123, 124, 125
len equ (($ - lst) / 8)

; ************************************************************************************
    section .text

    global _start
_start:

    mov ecx, len
    lea rbx, [lst]
    mov rdx, rbx
    xor edi,edi 
    xor eax,eax

.pushloop:
    push qword [rbx+rdi*8]
    add rdi,1
    dec ecx
    jnz .pushloop
    mov ecx, len
    xor edi, edi

mov ecx, len
xor edi, edi

.poploop:
    pop rax        ;Estracts all values one to one (in its correct order)

;----- This part contains some error and it needs fixed -----
    mov rcx, rax
    mov rdx, 3
    mov rbx, 1
    mov rax, 1
    syscall
; ---------------------------------------------------------------------------
    add rdi, 1
    dec ecx
    jnz .poploop

.exit:
   mov eax, 60
   xor edi,edi
   syscall

If someone finds a solution, it will make me very happy.

Good Luck.
« Last Edit: August 22, 2020, 08:25:56 AM by Ferran »

Offline fredericopissarra

  • Full Member
  • **
  • Posts: 368
  • Country: br
Re: Segment Default on linking elf64
« Reply #8 on: August 22, 2020, 02:01:44 PM »
Here, take a look:

Code: [Select]
; printlong.asm

  bits  64
  default rel

  section .text

  ; Entry: RAX = n (signed long).
  ; Destroy: RAX, RBX, RCX, RDX, RSI, RDI, R8 and R9.
  ;
  global printlong
printlong:
  lea   rsi,[rsp + 16] ; Points to the end of string.

  sub   rsp,40        ; allocate space on stack for string.

  mov   r8,rax        ; Holds a copy of n to test for signal later.
  xor   ecx,ecx       ; ECX will count how many chars in the buffer.

  mov   rbx,10        ; divisor on RBX.

  mov   r9,rax        ; Need R9 in loop below (holds que quotient).
.loop:
  mov   rax,r9        ; Gets old quotient.
  cqo                 ; Extends sign of RAX to RDX.
  idiv  rbx
  mov   r9,rax        ; New quotient in R9.

  test  rdx,rdx       ; Remainder is negative?
  jns   .notnegative  ; No. don't negate.
  neg   rdx           ; Yes. negate.
.notnegative:

  add   dl,'0'        ; store '0' + remainder and decrease pointer.
  mov   [rsi],dl
  dec   rsi

  inc   ecx           ; one more character on buffer.

  test  rax,rax       ; Quotient is zero?
  jnz   .loop         ; No. keep in loop.

  mov   edx,ecx       ; Move size to EDX because of syscall.

  test  r8,r8           ; n is negative?
  jns   .skipsignal     ; no. everything is ok.
  mov   byte [rsi],'-'  ; yes. add '-' to buffer.
  dec   rsi

  inc   edx
.skipsignal:

  inc   rsi           ; Points to the beginning of buffer.
  mov   eax,1         ; sys_write
  mov   edi,eax       ; stdout
  syscall

  add   rsp,40        ; deallocate space from stack.

  ret
Code: [Select]
; test.asm

  bits  64
  default rel

  section .rodata

lf: db  `\n`

  section .text

  extern printlong

  global _start
_start:
  mov   rax,-123
  call  printlong

  ; Prints final '\n'.
  mov   eax,1
  mov   edi,eax
  lea   rsi,[lf]
  mov   edx,eax
  syscall

  ; exit(0).
  xor   edi,edi
  mov   eax,60
  syscall
Code: [Select]
# Makefile
test: test.o printlong.o
ld -s -o $@ $^

test.o: test.asm
nasm -felf64 -o $@ $<

printlong.o: printlong.asm
nasm -felf64 -o $@ $<

.PHONY: clean

clean:
rm *.o

To test:
Code: [Select]
$ make
nasm -felf64 -o test.o test.asm
nasm -felf64 -o printlong.o printlong.asm
ld -s -o test test.o printlong.o
$ ./test
-123
$

[]s
Fred

Offline Ferran

  • Jr. Member
  • *
  • Posts: 23
  • Country: ad
Re: Segment Default on linking elf64
« Reply #9 on: August 24, 2020, 01:30:23 PM »
@federicopissarra I agree all this effort and latests but my intention is to resume in 1 function with all I want. I need to call it from other program beetween several other options, etc.

But today I want to show i'm very happy, because finally I gain all I wanted with this project, Impossible without your help and more other people who agree too.

Look at it:

Code: [Select]
; ***********************************************************************************
; array6.asm
; Exemple to learn how to use the stack to reverse a list of quadwords in place.
; Compile with nasm -f elf64 array6.asm
; Link with gcc -no-pie array6.o -o array6
; Run with ./array6
;
; Source: assembly64.pdf (version 1.1.40)
; Author: Ed Jorgensen Ph.D.
;
; (Modified for the Nasm Forum members for print the array values)
; ************************************************************************************

segment .data
lst:  dq 121, 122, -123, 124, 125
len equ (($ - lst) / 8)

a: dq 2
cnt: dq 0

fmt: dq "%lld ",10, 0
fmt_out: dq "The list is: ", 10, 0
lf: db  `\n`

segment .bss
array resq 5

segment .text
global main

extern printf

main:

; Subrutine for load all list values on stack ( @federicopissarra)

    push rbp
    mov ecx, len
    lea rbx, [lst]
    mov rdx, rbx
    xor edi,edi 
    xor eax,eax
 
    mov rdi, 4 ; I did reverse the order of values of array with a trick

.pushloop:
    push qword [rbx+rdi*8]
    sub rdi, 1
    dec ecx
    jnz .pushloop

    mov ecx, len
    xor edi, edi

.poploop:
    pop rax
    mov [array+rdi*8], rax
    add rdi,1
    dec ecx
    jnz .poploop

; Subrutine to print the values

.message:
mov rdi, fmt_out
call printf wrt ..plt

.printloop:
cmp rcx, 5
jz .printLineFeed
mov rax, [array+rcx*8]
inc rcx
mov [cnt], rcx

mov rdi, fmt
mov rsi, rax
call printf wrt ..plt
mov rcx, [cnt]
jmp .printloop

.printLineFeed:
    mov rdi, lf
mov rsi, rax
call printf wrt ..plt
 
.end:
mov rax, 0
pop rbp
ret

Now we will can to see the values in normal order (fifo list ---> lifo stack ---> fifo array ---> display).

The last task will be to try to dispense with the C commands for printing and to use strictly those of the assembly language. But by the moment it isn't needed.

I need to enjoy it a little bit :)

« Last Edit: August 26, 2020, 06:13:55 AM by Ferran »

Offline fredericopissarra

  • Full Member
  • **
  • Posts: 368
  • Country: br
Re: Segment Default on linking elf64
« Reply #10 on: August 25, 2020, 01:52:28 PM »
Ok, @Ferran, keep in mind there is a problem using libc functions in a pure assembly code.

High level language compilers does more than meet the eye. In particular, C compilers add an initialization and an finalization code to all hosted codes. This is not embeded in the library itself, but in separate object files.

You were lucky because printf() worked well, but this is not always the case.

If your routine will be used inside a C program, ok... otherwise, avoid using C oriented libraries. Anyway, if you are willing to use a C function in your pure assembly code, why bother? Why not develop entirely in C?

Offline Ferran

  • Jr. Member
  • *
  • Posts: 23
  • Country: ad
Re: Segment Default on linking elf64
« Reply #11 on: August 25, 2020, 10:40:45 PM »
I don't think I will have problems because I only need replay the model of this program. I'll tell you about it:

I have a project to create a very elementary and personalized programming language that is written in a .txt file. Each line of this file is read from a C file and then it is written inside a .asm file by means of fprintf() instructions. C works like an interpreter. E.g.:

Code: [Select]
if ( strcmp(token, "data") == 0 ) {
   fprintf(myfileasm, "section \t .data \n");
}

There will not be assembly code running as such embedded on C, only text lines lwritten in an .asm file. Once finished then I compile and link the .asm as always. 

Anyway I will continue trying to eradicate the "printf" of this program turning it into pure assembly code.
« Last Edit: August 25, 2020, 10:48:44 PM by Ferran »

Offline fredericopissarra

  • Full Member
  • **
  • Posts: 368
  • Country: br
Re: Segment Default on linking elf64
« Reply #12 on: August 26, 2020, 10:57:57 PM »
Anyway I will continue trying to eradicate the "printf" of this program turning it into pure assembly code.

I suggest you do the other way around. To create your parser/translator in C language instead of assembly. You'll need do code complex functions like binary trees to deal with expressions evaluations, for example, and to do this in ASM can be challenging.

Leave assembly to those funcions needing a boost of performance when you can't do it in C. Well... that's my advice.
« Last Edit: August 26, 2020, 10:59:31 PM by fredericopissarra »

Offline Ferran

  • Jr. Member
  • *
  • Posts: 23
  • Country: ad
Re: Segment Default on linking elf64
« Reply #13 on: August 27, 2020, 08:22:14 AM »
Fred:

Here is a sample of a program named sum.txt wrote in my language. It sums to 2 numbers (currently is in 32 bits):

Code: [Select]
; ---- Section .data ---- ;

data:

integerB Number1=12345                 ; This is an integer 'db'
integerB Number2=23456                 ; This is another 'db'

string Message="The result is:  "      ; This is another 'db' (string) finished with ,0
stringLF Result="     "              ; This is an empty field (5 blank spaces to fill) finished with 10, 0

; ---- Section text + global _start + _start lines: ---- ;
start:

sum Result=(Number1+Number2)          ; subrutine that sums 2 numbers into Resultat
show (Message)                        ; sys_write of Message
show (Result)                         ; sys_write of Result
exit                                  ; sys_exit


Once I proces with C this creates this sum.asm:

Code: [Select]
section .data
 
Number1 db '12345'
len_Number1 equ $ - Number1
Number2 db '23456'
len_Number2 equ $ - Number2
 
Message db "The result is: ", 0h
len_Message equ $ - Message
Result db "     ", 0Ah, 0h
len_Result equ $ - Result
 
 section .text

global _start
 _start:
 
mov esi, 4
mov ecx, 5
clc

add_loop:
mov al, [Number1 + esi]
adc al, [Number2 + esi]
aaa
pushf
or al, 30h
popf

mov [Result + esi], al
dec esi
loop add_loop

mov edx, len_Message
mov ecx, Message
mov ebx, 1
mov eax, 4
int 80h

mov edx, len_Result
mov ecx, Result
mov ebx, 1
mov eax, 4
int 80h

mov ebx, 0
mov eax, 1
int 80h

By the moment nothing happens. It is only an .asm code more. After i will need to compile and link to see the magic.

Code: [Select]
# ./builder sum.txt
# nasm -f elf sum.asm
# ld -m elf_i386 sum.o -o sum
# ./sum
The result is: 35801

I am very proud to have reached to this point without problems ;D That's why it was important for me to move towards the integration of the arrays in the builder, and so on...

Really doing this serves me to learn more and better every day the assembly code, the architectures, the syntax, etc. I am going to consider your advice, but I want to see up to where all this takes me because I see it as a very interesting challenge. If I cannot continue with this then I will change of project as you say.
« Last Edit: August 27, 2020, 08:39:31 AM by Ferran »