Recent Posts

Pages: [1] 2 3 ... 10
1
Programming with NASM / Re: nasm recursion
« Last post by fredericopissarra on February 12, 2020, 03:08:21 PM »
hello coders! Sorry, but I do not know English very well!

Welcome! I am not a native english speaker myself (brazillian!)

Quote from: vlobunet
on CIS forums, alas, there is no solution to my question. I am solving a problem. You need to display the number on the screen.
Which number? I didn't get it what you are trying to do...

Quote from: vlobunet
In assembler, the number comes from the si function and looks like this:
void ft_putnbr_fd(int nbr, int fd)
... where fd is a descriptor and nbr is a number that may be negative.
So, As I understand, you want to write 'nbr', in decimal, to the file descriptor 'fd'? Is so, here's a tip: Write the code in C, compile it and generate the assembly code and tweak it:
Code: [Select]
/* test.c */
static void write_buffer( int, void *, size_t );

void ft_putnbr_fd ( int nbr, int fd )
{
  // 10 bytes buffer (9 chars to 'ascii' numbers and 1 char to '-', if needed.
  char buffer[10];
  char *p, *q;
  int ch, tmp;

  // Points to the end of the buffer.
  p = q = buffer + sizeof buffer - 1;

  tmp = nbr;
  if ( tmp < 0 )
    tmp = -tmp;

  do
  {
    ch = tmp % 10;
    tmp /= 10;

    // Don't write left hand '0's...
    if ( ch || p == q )
      *p-- = ch + '0';
  } while ( tmp );

  // If negative, add '-' to the string.
  if ( nbr < 0 )
    *p = '-';
  else
    p++;  // not negative? points back to the beginning of the string.

  // write the string to fd.
  write_buffer( fd, p, sizeof buffer - ( p - buffer ) + 1 );
}

void write_buffer( int fd, void *ptr, size_t size )
{
#if ! defined( __linux__ ) && ! defined( __x86_64 )
#error This works only on x86-64 linux.
#endif

  __asm__ __volatile__ (
    "syscall"
    : : "a" (1), "D" (fd), "S" (ptr), "d" (size) : "r11"
  );
}

Take a look at the code GCC creates (test.s), in assembly, using: gcc -O2 -S -masm=intel test.c

One direct implementation based on this code could be:
Code: [Select]
; NASM x86-64 code for ft_putnbr_fd().
bits    64
default rel

section .text

global ft_putnbr_fd

; void ft_putnbr_fd( int nbr, int fd );
; ENTRY: edi = nbr, esi = fd
ft_putnbr_fd:
  ; Save registers that needed to be preserved.
  push  rbx

  ; Allocate 16 bytes in the stack (need to be QWORD aligned).
  sub   rsp,16

  ; Use r8 as pointer to the end of the buffer.
  mov   r8,rsp

  ; ECX is the counter of the number of chars in the buffer.
  xor   ecx,ecx

  mov   eax,edi       ; eax = tmp = nbr;
  test  edi,edi       ; TEST affect SF!
  jns   .positive
  neg   eax
.positive:

.loop:
  xor   edx,edx
  mov   ebx,10
  div   ebx           ; here eax = tmp / 10; edx = tmp % 10
                      ; GCC change this to a multiplication, which is faster!

  test  edx,edx
  jnz   .store
  cmp   rsp,r8        ; Just store '0' if we are at the end of the buffer.
  je    .store

  test  eax,eax       ; while tmp isn't 0, stay in the loop.
  jnz   .loop

  test  edi,edi
  jns   .advance
  add   ecx,1
  mov   byte [r8],'-'
  jmp   .continue
.advance:
  add   r8,1
.continue:

  ; Write syscall.
  mov   eax,1   ; WRITE syscall
  mov   edi,esi ; fd
  mov   rsi,r8  ; points to buffer.
  mov   edx,ecx ; size of the buffer.
  syscall
 
  ; Dealloate 16 bytes from stack.
  add   rsp,16

  ; Restore registers that needed to be preserved.
  pop   rbx

  ; Return to the caller.
  ret

  ; Store DL in the buffer and returns to the loop.
.store:
  add   dl,'0'
  mov   [r8],dl
  add   ecx,1
  sub   r8,1
  jmp   .loop

2
Programming with NASM / Re: nasm recursion
« Last post by Frank Kotler on February 11, 2020, 11:25:42 PM »
Hi viobunet.
Welcome to the Forum.

I don't know, but:
Code: [Select]
mov rsp, 45
doesn't look right to me. Did you mean
Code: [Select]
mov [rsp], 45
?
"45" may not be valid memory. Sorry I can't help more...

Best,
Frank


3
Using NASM / Re: Input integers to Intel x86 NASM through C
« Last post by fredericopissarra on February 11, 2020, 12:23:14 PM »
Since you are using GCC, if you really need an assembly version for your sum() function, I recomend using inline assembly to avoid unecessary calls:
Code: [Select]
// this works in every Intel/AMD processors...
#define sum(s,a,b) \
  __asm__ __volatile__ ( "leal (%1,%2),%0" : \
    "=r" ((s)) : "r" ((a)), "r" ((b)) );
...
  int r, a, b;
...
  sum(r,a,b);
4
Using NASM / Re: Input integers to Intel x86 NASM through C
« Last post by fredericopissarra on February 11, 2020, 09:53:17 AM »
Here's three shorter versions:

Code: [Select]
; sum32.asm - 32 bits version (linux + windows) - cdecl.
bits  32

section .text

; Instead of remembering where the arguments
; are on the stack, you can use a structure like this:
struc sumstkfrm
.retaddr:   resd  1  ; return address
.b:         resd  1
.a:         resd  1
endstruc

; int sum( int a, int b );
global sum
sum:
  mov eax, [esp + sumstkfrm.a]
  add eax, [esp + sumstkfrm.b]
  ret

Code: [Select]
; sumx86-64-linux.asm
; for Linux amd64 version.
bits 64

section .text

; int sum( int a, int b );
global sum
sum:
  lea  eax, [rdi+rsi]
  ret

Code: [Select]
; sumx86-64-windows.asm
; for Windows x64 version.
bits 64

section .text

; int sum( int a, int b );
global sum
sum:
  lea  eax, [rcx+rdx]
  ret
5
Programming with NASM / nasm recursion
« Last post by vlobunet on February 11, 2020, 06:14:50 AM »
hello coders! Sorry, but I do not know English very well!  on CIS forums, alas, there is no solution to my question. I am solving a problem. You need to display the number on the screen. In assembler, the number comes from the si function and looks like this:
void ft_putnbr_fd(int nbr, int fd)
... where fd is a descriptor and nbr is a number that may be negative.
I check the number first. if it is greater than or equal to 0, then I go to the body of recursion (_body). otherwise, I display the symbol '-' on the screen, and I make the number positive.
In the recursion body, I save the whole and the remainder each time on the stack. after that I divide the integer by 10. if after dividing the integer value is greater than 0 then I go to _body and when the integer is 0 I go to the output of _display
and here I have problems. I am using lldb debugger, intel mnemonics, x86_64, ios
during debugging, I go all the way to _display but after displaying the character on the screen, I see the following message:
->  0x100000dd4 <+26>: retq
0x100000dd5:       nop
0x100000dd6:       nop
0x100000dd7:       nop
after that the program crashes.
my code

%define CALL(n)      0x2000000 | n
%define WRITE      4

global  _ft_putnbr_fd
extern  _ft_putchar_fd

section .data
   pos dq 0
   minus db '-'

section .text

_ft_putnbr_fd:
   push   rbp;
   mov      rbp, rsp;

   mov      rax, rdi
   mov      rdx, 0
   cmp      rax, 0
   jae      _body
   neg      rax
   push   rax
   mov      rsp, 45
   call   _ft_putchar_fd
   pop      rax
   jmp      _body
   ret


_body:
   push   rdx
   xor      rdx, rdx
   mov      rcx, 10
   div      rcx
   cmp      rax, 0
   jne      _body
   jmp      _display
   ret

_display:
   add    rdx, '0'
   push   rdi
   mov      rdx, 1
   mov      rdi, rsi
   mov      rsi, rdx
   mov      rax, CALL(WRITE)
   syscall

   pop      rdi
   ;call   _ft_putchar_fd
   pop      rdx
   ret
6
Using NASM / Re: Input integers to Intel x86 NASM through C
« Last post by ImConfussed on February 10, 2020, 02:27:14 PM »
Done. Maybe this is useful for someone, so:

Code: [Select]
%include "asm_io.inc"

segment .text
    global calc_sum

calc_sum:
    enter       4, 0
    push        ebx
    ;dump_stack  1, 0, 6

    mov         ebx,[ebp+16] 
    mov         eax,[ebp+8]       ; [ebp+8] = num1
    add         eax,[ebp+12]      ; [ebp+12] = num2
    ; if I were to have num3, then it would be [ebp+16], and the currently [ebp+16], would now be on [ebp+20]

    mov         [ebx],eax

    pop         ebx
    leave
    ret
7
Using NASM / Input integers to Intel x86 NASM through C
« Last post by ImConfussed on February 08, 2020, 10:45:33 PM »
Hello. I have an assignment where I have to calculate the determinant of a matrix on Intel x86 with NASM, but I have to take the elements of the matrix and show the final result using C.
My problem: I (and all my classmates) started from 0 with NASM, and all we have is Paul Carter's PC Assembly book.

I managed to do an incredible poor .asm where I ask for 4 inputs, store each one of them on 4 variables declared on the .bss section and then do the math (as if those for numbers where the elements of a 2x2 matrix).

Carter's book goes from easy to hard in no time. I can not do a simple program where I ask for 2 numbers in C (using scanf("%d %d", &num1, &num2)), add them on NASM and return the value to C to show it.

My C code is simple:
Code: [Select]
#include <stdio.h>

void calc_sum(int, int, int*) __attribute__((cdecl));

int main(void)
{
    int num1, num2, sum;
    printf("Input two numbers: ");
    scanf("%d %d", &num1, &num2);
    calc_sum(num1, num2, &sum);          // here the .asm does result = num1 + num2 and returns the result
    printf("Sum is %d\n", sum);
}

(if there is a typo is because I'm retyping it from my VM with Ubuntu 18.04 to Windows)

Someone knows of a guide o a place with basics examples, or can help me with this (not the determinant, but implementing this C code in a .asm)?
8
Programming with NASM / Re: Determine Parameter Type
« Last post by debs3759 on February 03, 2020, 12:15:15 AM »
If dbString is defined as

#define dbString "string"

or

dbString db "string"

then the two will be seen as the same when assembled. I am not aware of a way for the two to be differentiated with the two lines you posted. This is because the preprocessor substitutes "string" where it sees dbString.
9
Programming with NASM / Determine Parameter Type
« Last post by Structure on February 02, 2020, 09:18:14 PM »
How can i find out the parameter type passed to a macro...

Code: [Select]
runMacro dbString
Code: [Select]
runMacro "string"
I believe the compiler recognizes both of these as strings?
How can i differentiate between these two and run different commands based on that ?
10
Other Discussion / Re: Delay in starting a program.
« Last post by Structure on January 29, 2020, 07:24:59 PM »
Quote
The Task Scheduler enables you to automatically perform routine tasks on a chosen computer. Task Scheduler does this by monitoring whatever criteria you choose (referred to as triggers) and then executing the tasks when those criteria are met.

https://docs.microsoft.com/en-us/windows/win32/taskschd/task-scheduler-start-page
Pages: [1] 2 3 ... 10