Recent Posts

Pages: 1 2 [3] 4 5 ... 10
21
If you want to use your routines called from C functions, you need to obey the calling SysV ABI convention (since you are dealing with ELF). In amd64 code the first 6 "integer" arguments (including pointers) are passed through registers: RDI, RSI, RDX, RCX, R8 and R9. If you use floating point arguments, the 7 first are passed through XMM0-XMM7.

So, your slen funcion should be:
Code: [Select]
; size_t slen( char *s );
slen:
  xor eax,eax   ; EAX is used as counter.
.loop:
  cmp byte [rdi],0
  jz  .exit
  add rax,1
  add rdi,1
  jmp .loop
.exit:
  ret

Yet, syscalls called though 'int 0x80' lacks support for 64 bits pointers. You should use 'syscall' instruction (with different function id for write()):
Code: [Select]
sprint:
  mov rsi, rdi  ; save RDI on RSI (RSI used by write syscall).
  call  slen
  mov rdx, rax  ; RDX is the string length.
  mov eax, 1    ; write syscall
  mov edi, eax  ; stdout
  syscall
  ret

sprintF:
  call sprint

  mov eax,1
  mov edx,eax
  mov edi,eax
  lea  rsi,[lf]
  syscall
  ret
lf: db `\n`

OBS: When you change an E?? register, the upper 32 bits of R?? register is zeroed, autmatically.
22
Don't the print routines usually expect the trailing line feed to be part of the string input? I have never seen one which add a line feed to the string you send it. That shouldn't cause your error though. I have never coded for Linux or 64-bit though, so I may be wrong. I only know 8 bit to 32 bit code, but am surprised if protocols are all that different. Your code looks rather complex for just outputting a simple string.
23
Programming with NASM / Trying to convert 32-bit code into 64-bit: Line feed ignored
« Last post by cid on July 28, 2019, 09:22:09 AM »
Hello, recently I found this nasm tutorial https://asmtutor.com/#lesson7. Unfortunately, there is no 32-bit version of the code. I want to convert some of the code in 64-bit (elf64 on linux) but I stuck on the sprintlf 'function'. This section should print the string in the eax register and a line feed by calling the sprint function twice. My problem is that this function acts as the normal sprint function: \n or 0Ah byte is ignored while executing. Maybe it has something to do with the stack register or the compare instruction.

To compile the program in elf64 I had to convert all 32-bit registers like eax, esp... to their 64-bit equivalents: rax,rsp...

This is my modified version:
Code: [Select]
;------------------------------------------
; int slen(String message)
; String length calculation function
slen:
    push    rbx
    mov     rbx, rax
 
nextchar:
    cmp     byte [rax], 0
    jz      finished
    inc     rax
    jmp     nextchar
 
finished:
    sub     rax, rbx
    pop     rbx
    ret
 
 
;------------------------------------------
; void sprint(String message)
; String printing function
sprint:
    push    rdx
    push    rcx
    push    rbx
    push    rax
    call    slen
 
    mov     rdx, rax
    pop     rax
 
    mov     rcx, rax
    mov     rbx, 1
    mov     rax, 4
    int     80h
 
    pop     rbx
    pop     rcx
    pop     rdx
    ret
 
 
;------------------------------------------
; void sprintLF(String message)
; String printing with line feed function
sprintLF:
    call    sprint
 
    push    rax         ; push rax onto the stack to preserve it while we use the rax register in this function
    mov     rax, 0Ah    ; move 0Ah into rax - 0Ah is the ascii character for a linefeed
    push    rax         ; push the linefeed onto the stack so we can get the address
    mov     rax, rsp    ; move the address of the current stack pointer into rax for sprint
    call    sprint      ; call our sprint function
    pop     rax         ; remove our linefeed character from the stack
    pop     rax         ; restore the original value of rax before our function was called
    ret                 ; return to our program
Output when moving "Hello World" to rax, calling sprintlf and repeat the steps again: Hello WorldHello World
The line feed is not printed.
24
Programming with NASM / Re: [dos 16-bit] assembly from c using openwatcom
« Last post by mohammadk on July 28, 2019, 07:56:09 AM »
Agreed, and thanks for the tip, I tried it "--postfix _" and it worked :)
combined with macros I can now write asm code compatible with multiple compilers.
Moh.K.
25
Programming with NASM / Re: [dos 16-bit] assembly from c using openwatcom
« Last post by Frank Kotler on July 27, 2019, 11:02:17 PM »
Thanks for the update Mohammadk. I don't know how we're supposed to know this stuff. Sometimes C wants a leading underscore, sometimes it wants a trailing underscore, sometimes it wants no underscore at all. Nasm has "--prefix" and "--postfix" which will help with it. Glad you figured it out!

Best.
Frank

26
Programming with NASM / Re: [dos 16-bit] assembly from c using openwatcom
« Last post by mohammadk on July 27, 2019, 09:18:08 PM »
For anyone wondering,
I've been confusing myself between nasm and ow documentations.
ow uses it's own calling conventions by default, which explains the needed trailing "_ " after the procedure name like this "add_int_".
but when used with -ecc option it can revert to __cdecl which will require an "_" prefix like this "_add_int"
This also affects parameter passing which by default uses the registers (dx, ax then bx then cx then the stack) instead of the stack all the way.

so finally the modified ADDINT.ASM looks like this:
Code: [Select]

; nasm -f obj ADDINT.ASM
; wcl -mm ADDINT.OBJ EXT.C (for ow conventions - parameters pssed on registers, use add_int_)
; wcl -mm -ecc ADDINT.OBJ EXT.C (for __cdecl conventions - parameters passed on the stack, use _add_int)
segment _TEXT public class=CODE   
global add_int_
add_int_:
push bp
mov bp,sp
sub sp, 0x40 ; 64 bytes of local stack space
add ax, dx ; first parameter is passed into dx, 2nd into ax
mov sp, bp ; undo "sub sp, 0x40"
pop bp
retf                ; medium model ret

27
Programming with NASM / Re: [dos 16-bit] assembly from c using openwatcom
« Last post by mohammadk on July 27, 2019, 05:22:52 PM »
 :-[  That solved it
many thanks  8)
28
Programming with NASM / Re: [dos 16-bit] assembly from c using openwatcom
« Last post by Frank Kotler on July 27, 2019, 04:45:37 PM »
Try "add_int_" with the underscore at the end (in your .asm file). I think that's the way Watcom likes it.

Best,
Frank

29
Programming with NASM / [dos 16-bit] assembly from c using openwatcom
« Last post by mohammadk on July 27, 2019, 04:00:08 PM »
Hi,

I'm having trouble compiling a c program which calls a simple assembly procedure.
This is intended as a medium 16-bit exe.

asm code: ADDINT.ASM
Code: [Select]
%define xparam [bp+6]            ; using medium memory model
%define yparam [bp+8]           

segment _TEXT public class=CODE   
global add_int
add_int:
push bp
mov bp,sp
sub sp, 0x40 ; 64 bytes of local stack space
mov ax, xparam
add ax, yparam
mov sp, bp ; undo "sub sp, 0x40"
pop bp
retf                            ; medium model ret


C code: EXT.C
Code: [Select]
#include <stdio.h>

extern int add_int(int x, int y);

void main(void)
{
int third = add_int(9, 1);
printf("third = %d\n", third);
}


compilation:
Code: [Select]
nasm -f obj ADDINT.ASM
wcl -mm ADDINT.OBJ EXT.C

Errors:
Code: [Select]
Open Watcom C/C++ x86 16-bit Compile and Link Utility
Version 2.0 beta Jul 16 2019 17:31:29 (16-bit)
Copyright (c) 2002-2019 The Open Watcom Contributors. All Rights Reserved.
Portions Copyright (c) 1988-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.
See http://www.openwatcom.org/ for details.
wcc EXT.C  -mm
Open Watcom C x86 16-bit Optimizing Compiler
Version 2.0 beta Jul 16 2019 17:23:09 (32-bit)
Copyright (c) 2002-2019 The Open Watcom Contributors. All Rights Reserved.
Portions Copyright (c) 1984-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.
See http://www.openwatcom.org/ for details.
EXT.C: 9 lines, included 799, 0 warnings, 0 errors
Code size: 35
wlink @__wcl__.lnk
Open Watcom Linker Version 2.0 beta Jul 16 2019 17:20:15 (32-bit)
Copyright (c) 2002-2019 The Open Watcom Contributors. All Rights Reserved.
Portions Copyright (c) 1985-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.
See http://www.openwatcom.org/ for details.
loading object files
searching libraries
Error! E2028: add_int_ is an undefined reference
creating a DOS executable
file EXT.obj(C:\DOS\DEV\TRICKS\EXT\EXT.C): undefined symbol add_int_
Error: Linker returned a bad status


I'm running on dosbox
30
Programming with NASM / Re: Disable relocation, or specify constant to WRT?
« Last post by Frank Kotler on July 26, 2019, 04:08:34 AM »
Hi anyfoo,

I dunno. My example segfaults because there's no physical
memory mapped to virtual zero, where my variable is. No surprise.

I'm not too surprised that ld balks at a 16-bit relocation, but I don't know much about the inner workings of ld. My attempt to use wrt got a message that ld didn't use wrt "that way". It uses "wrt got" or "wrt plt", ect. If your environment has a Global Offset Table and/or a Procedure Llnkage Table, maybe you could use them?

Perhaps you could modify the code in outelf,c to not generate a relocation entry in certain cases, I don't know what ld would think about that.

I think you're really over my head here. I doubt if I''m going to be able to help you much...

Best,
Frank


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