Recent Posts

Pages: 1 2 [3] 4 5 ... 10
21
Programming with NASM / Re: Segmentation fault question
« Last post by fredericopissarra on May 27, 2019, 08:36:02 PM »
A simple test:
Code: [Select]
  ; asm.asm
  bits  64
  default rel

  section .text

  global  f

; unsigned long long f( unsigned long long );
; Entry: RDI
; Output: RAX
f:
  mov rax,rdi
  mov eax,1   ; it will zero the upper 32 bits?
  ret
Code: [Select]
/* test.c */
#include <stdio.h>

extern unsigned long long f( unsigned long long );

int main( void )
{
  unsigned long long x;

  x = f(0xffffffffffffffffULL); // all bits set.

  // Maybe it will print 0xffffffff00000001?! Nah!
  printf( "%#016llx\n", x );
}
Code: [Select]
# Makefile
test: test.o asm.o
$(CC) -o $@ $^

test.o: test.c

asm.o: asm.asm
nasm -felf64 -o $@ $<
Just:
Quote
$ make
$ ./test
22
Programming with NASM / Re: Segmentation fault question
« Last post by fredericopissarra on May 27, 2019, 08:24:38 PM »
oh wow.  talk about stupidity... rax - 64bit, eax -32 bit, ax - 16 bit al or ah is 8 bit.. of the same register. if I read another post nasm through optimization selects the smallest form. 64 bits addresses are 3 or 4 bytes long, 32 bit are 2.  that is code generation, it is in the prefixes on the byte sequence to denote 16, 32, 64 bit number that follows..

it could be your fallacy, if you forget there is a full 64 bit number in a register when you only zero out 32 bits of the register, it does not end up 0..
So, what if you read from Intel and AMD themselves... READ the Development Manuals and see for yourself.

23
Programming with NASM / Re: Segmentation fault question
« Last post by azagaros on May 27, 2019, 07:25:38 PM »
oh wow.  talk about stupidity... rax - 64bit, eax -32 bit, ax - 16 bit al or ah is 8 bit.. of the same register. if I read another post nasm through optimization selects the smallest form. 64 bits addresses are 3 or 4 bytes long, 32 bit are 2.  that is code generation, it is in the prefixes on the byte sequence to denote 16, 32, 64 bit number that follows..

it could be your fallacy, if you forget there is a full 64 bit number in a register when you only zero out 32 bits of the register, it does not end up 0..
24
Programming with NASM / Re: Segmentation fault question
« Last post by fredericopissarra on May 27, 2019, 07:16:26 PM »
Another thing: Avoid using R?? registers if you can. If you need a simple counter, 32 bits will sufice and you should use E??. This because using R?? for other thing than pointers will add an REX prefix to instructions and the imediate values will be 64 bits long...

XOR EAX,EAX will clear the entire RAX and it is a shorter instruction... Every instruction which deals with E?? registers will erase, automatically the upper bits of R?? registers...

To load an effective address (pointer), you should use LEA instruction to take advantage of RIP relative addressing. This:

MOV RDI,strNewLine

Is better defined as

LEA RDI,[strNewLine]

Because it is wise do prefer Position Indementent Executables (PIE) in x86-64 mode.
25
Programming with NASM / Re: Segmentation fault question
« Last post by fredericopissarra on May 27, 2019, 06:59:08 PM »
Take a closer look at your printstr function... What registers it changes?
26
Programming with NASM / Re: Segmentation fault question
« Last post by azagaros on May 27, 2019, 06:35:55 PM »
First off tell me where I am touching anything but the system calls.. I am not making the function calls.  It appears the registers get trashed in a task switch of linux.  Assembly has always been the argument of the registers.  I save registers if I do not care what they return as from process.  I am being specific about the calls and when I do them. Most of the registers I have not touched.  I have read the abi backwards and forwards more times that care to realize.  I have something interfering with position by most addressing models that should not move, so any number I move from x to y, it does not change that number.  If it gets relocated by the OS, the os should clean up the pointers.  I am crossing a boundary because a number changed by some abstract.  My assembly do not change any numbers and I expect enter and exit of any function to change certian numbers.  Which stupidity am I really following doing simple assembly? I have been chasing bugs like every time I code something on linux in 64 bit and have been doing assembly for 30+ years..
27
Programming with NASM / Re: Segmentation fault question
« Last post by fredericopissarra on May 27, 2019, 06:06:44 PM »
SysV ABI amd64 calling convention:

The integer arguments (or pointers) are passed to a function in order: RDI, RSI, RDX, RCX, R8 and R9, from 7th argument to the last, they are stored on stack cdecl style. For syscalls, instead of RCX, R10 is used.

For floating point, XMM0 to XMM7 will be used for arguments.

Example: int f( int a, float b, int c ); // EDI=a, XMM0=b, ESI=c

Registers RSP, RBP, RBX and R12 to R15 must be preserved between calls. Any other registers can be changed inside a function.

RAX is the returned value...
28
Programming with NASM / Re: Segmentation fault question
« Last post by azagaros on May 27, 2019, 04:57:14 PM »
Thank you Fredericopissarra.  You got me by one stumbling block.  Just trying to understand how the registers and stack on linux are handled is being challenging.  A small expansion of code has created a new segmentation fault.
Code: [Select]
    bits 64
    default rel  ; x86-64 default addressing is RIP Relative


; section .data

section .rodata
strNewLine   db 10
strSpace     db 32
strFileName  db 'is a file name.',0
strOption    db 'is an option flag.',0
   
   
section .text
    global _start
_start:
    xor rbx, rbx    ;zero the rbx- will not get trashed by sys v abi (the system calls)
   
    ; rsp is the **argv
.argloop:
    mov rdi, [rsp+rbx*8+8]
    test rdi, rdi   ; testing for null
    jz .noMoreArg   ; jump on zero
    cmp rbx, 0      ; consuming the first arg.
    je .skipProcess
    call printstr   ; print the string
    call printSpc   ; print a space
    ; procecc the arg
    call processArg
    call printnl    ; print a new line character
.skipProcess:
    add rbx, 1      ; increment the index.
    jmp .argloop

.noMoreArg:   
    call ExitProg
    ret
   
; rdi = string ptr   
strlen:
    xor rax, rax    ; zero rax register
.loop:
    cmp byte[rdi+rax],0  ;check for null termination of string
    jz .strlenend
    add rax,1
    jmp .loop
.strlenend:
    ret

; rdi = str ptr
printstr:
    call strlen
    mov rdx, rax  ; store the length rdx
   
    mov rax, 1    ; syscall write
    mov rsi, rdi  ; str ptr
    mov rdi, rax  ; stdout
    syscall
    ret
   
; rdi = str ptr
printnl:
    mov rax, 1
    mov rdi, rax
    mov rdx, rax
    lea rsi, [strNewLine]
    syscall
    ret

;rdi = str ptr
printSpc:
    mov rax, 1
    mov rdi, rax
    mov rdx, rax
    lea rsi, [strSpace]
    syscall
    ret

; rdi = str ptr to process       
processArg:
    xor rax, rax  ;string index position
    cmp byte[rdi+rax],'-'
    je .argOption
    ; is the stack getting trashed? stack alignment? (system calls use the local stack?)
    push rdi   ; save the current rdi (should not change)
    push rax   ; save the working rax (It is getting trashed?) (it gets trashed in the string length function)
    mov rdi, strFileName  ; set up a differnet rdi...
    call printstr
    pop rax
    pop rdi
    ;Assumed file concept (can have more than one)
    ;allocate a file infromation block
    ;copy the file name to the file name of the block
.argOption:
    add rax, 1  ;consume the option flag
    ; the test for the list of options.
    push rax
    push rdi
    mov rdi, strOption
    call printstr
    pop rdi
    pop rax
   
    ret
     
ExitProg:

   xor rdi, rdi
   mov rax, 60
   syscall

As for you Kolter as a NASM developer some food for thought:
https://eli.thegreenplace.net/2012/01/03/understanding-the-x64-code-models

every thing I am fighting seems to be in the code generation of Nasm or Fasm for that matter
29
Programming with NASM / Re: Segmentation fault question
« Last post by fredericopissarra on May 26, 2019, 10:16:51 PM »
Maybe this could help:
Code: [Select]
; test.asm
;
; compile with:
;   $ nasm -felf64 -o test.o test.asm
;   $ ld -o test test.o
;
    bits 64
    default rel   ; x86-64 default addressing is RIP relative!

    ; Moved to .rodata.
    section .rodata

strNewLine:  db `\n`
   
    section .text

    global _start
_start:
    ; argc is in [rsp]
    ; argv[n] are in [rsp+8*n+8]
    ;mov   ecx,[rsp]  ; argc (not used here!)

    xor   ebx,ebx     ; RBX is saved by syscalls (SysV ABI).
                      ; Used as index...
.loop:
    mov   rdi,[rsp+rbx*8+8]
    test  rdi,rdi     ; argv[rbx] == NULL?
    jz    .no_more_args
    call  printstr    ; print the string
    call  printnl     ; print a new line character
    add   ebx,1       ; avoid using INC/DEC (they are slow!).
    jmp   .loop
   
.no_more_args:
    mov   eax,60    ; syscall_exit
    xor   edi,edi   ; exit(0).
    syscall
   
; rdi = string ptr.
strlen:
    xor   eax,eax
.loop:
    cmp   byte [rdi+rax],0
    jz    .strlen_end
    add   eax,1
    jmp   .loop
.strlen_end:
    ret

;rdi = string ptr
printstr:
    call  strlen
    mov   edx,eax    ; string length.

    mov   eax,1      ; syscall_write
    mov   rsi,rdi    ; string ptr.
    mov   edi,eax    ; stdout
    syscall
    ret

printnl:
    mov   eax,1       ; syscall_write
    mov   edi,eax     ; stdout
    mov   edx,eax     ; 1 char do print
    lea   rsi,[strNewLine]  ; points to '\n'.
    syscall
    ret
30
Programming with NASM / Re: Segmentation fault question
« Last post by Frank Kotler on May 26, 2019, 10:15:39 PM »
I am not good on 64-bit code. It looks like rcx is being trashed in one of your routines. Either save rcx across the two routines, or test rax for zero instead of counting on argc.

I think that'll work...

Best,
Frank


Pages: 1 2 [3] 4 5 ... 10