Recent Posts

Pages: 1 ... 3 4 [5] 6 7 ... 10
41
Programming with NASM / Re: Problem with calculating root
« Last post by fredericopissarra on January 30, 2025, 07:07:16 PM »
I'll assume you just want to extract the square root of an integer value and get an integer result using `sqrtsd` instruction...

First: double type has 53 bits of precision and 11 bits in the expoent of the scale factor plus the signal bit. This means a double is 64 bits long (but with less precision than an long long int)... Let's say your function is defined to obey SysV ABI for x86-64 (not for Windows):

Code: [Select]
; unsigned long long int sqrtroot( unsigned long long int x );
; Entry: RDI = x
; Exit: RAX
  global sqrtroot

  align 4
sqrtroot:
  cvtsi2sd xmm0,rdi      ; Convert RDI to double scalar in XMM0.
  sqrtsd xmm0,xmm0       ; xmm0 = sqrt(xmm0)
  cvtsd2si rax,xmm0      ; Convert XMM0 double scalar to RAX (this convertion applies rounding).
  ret
For Windows change RDI to RCX.

If you want to use unsigned int, instead, you need to zero the upper 32 bits of RDI:
Code: [Select]
; unsigned int sqrtroot( unsigned int x );
; Entry: EDI = x
; Exit: EAX
  global sqrtroot

  align 4
sqrtroot:
  mov edi,edi
  cvtsi2sd xmm0,rdi      ; Convert RDI to double scalar in XMM0.
  sqrtsd xmm0,xmm0       ; xmm0 = sqrt(xmm0)
  cvtsd2si rax,xmm0      ; Convert XMM0 double scalar to RAX (this convertion applies rounding).
  ret
PS: GCC makes sure the upper double from xmm0 is zero beginning with pxor xmm0,xmm0, but we don't need to do this since we're dealing only with an scalar...
42
Programming with NASM / Re: Problem with calculating root
« Last post by fredericopissarra on January 30, 2025, 06:47:16 PM »
First of all: What do you want to do?
43
Programming with NASM / Problem with calculating root
« Last post by andyz74 on January 29, 2025, 09:35:26 PM »
Hello all of you,
I am sure, this is a absolutely stupid failure of mine, but I don' get it...  so, please have a look and see, if you are able to find the problem

Code: [Select]
get_wu:
mov rbx, qword [para_w] ; load my value to rbx to ensure I can see in debugger if it is right
movsd xmm1, qword [para_w]                                ;  get my value to xmm1 
sqrtsd xmm0, xmm1                                          ; take root of xmm1 and save it to xmm0
cvttsd2si rbx, xmm0                                               ; convert (and truncate) xmm0 to integer and store it in rbx
inc rbx
ret


in the debugger I see, that rbx and xmm1 are correct loaded with my value,
after the sqrtsd , I see "something" in xmm0, which I assume it is my packed calculated root
and after the cvttsd2si, I have always 0 (zero)  in my rbx. not a correct calculated root.

Please, what am I doing wrong?

Note:  I do not need the correct root, but the integer part has to be correct.  (sqrt(10)  => 3) is good for me
44
Programming with NASM / Re: Converting MASM TSR in DOS and NASM
« Last post by tysonprogrammer on January 04, 2025, 12:00:21 AM »
I found the error of my ways, I needed to use jmp far [cs:old_interupt9]

Now to see why it's not detecting the keys and disabling the normal CTRL+ALT+DEL

So I have this book that has an example TSR written in MASM, al it doe sit look at the keyboard flags and if the user presses CTRL+ALT+DEL is if change turns off the CTRL bit. If the user pressss CTRL_ALT_Rgt Shift+DEL is will original handler.

I pretty much have it  working except after it installs I can no longer type anything so I am guessing it's not calling the old handler. I am pretty sure I have the jump addresses incorrect but not sure how to get that working.

I had originally pasted int the MASM source but was concerned that it might be copyrighted so I removed it and I removed unrelated code from my version as I believe the issue is either setting the interrupt vector or the jumping to the original one. Perhaps I am not jumping correctly.

Code: [Select]
org 100h

main:
jmp setup

int9_handler:
sti                                 ; enable hardware interupts
pushf                               ; save regs and flags
push es
push ax
push di

pop di
pop ax
pop es
popf
jmp [cs:old_interupt9]

old_interupt9 dw 2 dup (?)
end_isr: db 1 dup (?)
; ----------------------------------------------
; Save copy of original interrupt 9 vector, and setup
; the address of the program as the new vector, terminate
; this program and leave int9_handler procedure in memory.
setup:
mov ax, 0x3509                      ; get int9 vector
int 0x21

mov word [old_interupt9], bx        ; save int9 vector
mov word [old_interupt9+2], es

mov ax, 0x2509                      ; set int9 vector
mov dx, int9_handler
int 0x21

mov ax, 0x3100                      ; terminate and stay resident
mov dx, end_isr                     ; point to end of resident code
shr dx, 4                           ; divide by 16
inc dx                              ; round forward one paragraph
int 0x21


What am I missing?


thanks,
Tyson
45
Programming with NASM / Converting MASM TSR in DOS and NASM
« Last post by tysonprogrammer on January 02, 2025, 11:29:39 PM »
So I have this book that has an example TSR written in MASM, al it doe sit look at the keyboard flags and if the user presses CTRL+ALT+DEL is if change turns off the CTRL bit. If the user pressss CTRL_ALT_Rgt Shift+DEL is will original handler.

I pretty much have it  working except after it installs I can no longer type anything so I am guessing it's not calling the old handler. I am pretty sure I have the jump addresses incorrect but not sure how to get that working.

I had originally pasted int the MASM source but was concerned that it might be copyrighted so I removed it and I removed unrelated code from my version as I believe the issue is either setting the interrupt vector or the jumping to the original one. Perhaps I am not jumping correctly.

Code: [Select]
org 100h

main:
jmp setup

int9_handler:
sti                                 ; enable hardware interupts
pushf                               ; save regs and flags
push es
push ax
push di

pop di
pop ax
pop es
popf
jmp [cs:old_interupt9]

old_interupt9 dw 2 dup (?)
end_isr: db 1 dup (?)
; ----------------------------------------------
; Save copy of original interrupt 9 vector, and setup
; the address of the program as the new vector, terminate
; this program and leave int9_handler procedure in memory.
setup:
mov ax, 0x3509                      ; get int9 vector
int 0x21

mov word [old_interupt9], bx        ; save int9 vector
mov word [old_interupt9+2], es

mov ax, 0x2509                      ; set int9 vector
mov dx, int9_handler
int 0x21

mov ax, 0x3100                      ; terminate and stay resident
mov dx, end_isr                     ; point to end of resident code
shr dx, 4                           ; divide by 16
inc dx                              ; round forward one paragraph
int 0x21


What am I missing?


thanks,
Tyson

46
Programming with NASM / Re: Printing numbers with stack as variable
« Last post by andyz74 on December 29, 2024, 07:25:27 PM »
Many many thanks, I will check this as soon as I will be back at my Computer. Many thanks!
47
Programming with NASM / Re: Printing numbers with stack as variable
« Last post by fredericopissarra on December 29, 2024, 05:40:49 PM »
Would have been happy to know, why mine does not work es expected
To push QWORDs with each character calculated in the first loop is a huge waste of stack space. It is simplier to pre-alocate the space (10 chars for a DWORD converted in decimal string), but keeping RSP QWORD (or DQWORD) aligned.

Here's your code modified:
Code: [Select]
  bits  64
  default rel

  section .text

  global _start
_start:
  sub   rsp,8+16      ; Align by DQWORD and reserve space to the string.
                      ; We only need 11 bytes allocated, but we need to keep
                      ; RSP aligned.
                      ;
                      ; Don't really need to keep RSP aligned to DQWORD in this
                      ; code, but it is a good practice in case we use SSE/SSE2.

  mov   rsi,rsp       ; Using RSI because sys_write needs it.

  mov   eax, 1234     ; # to print.
  xor   ecx, ecx      ; Counter = 0.

  mov   byte [rsi],`\n`
  mov   ebx, 10

  align 4
.loop:
  dec   rsi
  xor   edx, edx
  div   ebx     
  add   dl, '0'

  mov   [rsi],dl

  inc   rcx           ; Increment counter.
  test  eax, eax      ; Quotient == 0?
  jnz   .loop         ; No, stay in the loop.

  ; sys_write.
  mov   eax,1
  mov   edi,eax
  lea   edx,[rcx+1]   ; The final '\n' as well.
  syscall

  add   rsp,8+16      ; Restore RSP to its original position.
                      ; Not really needed since sys_exit will not return.

  ; FIXED: Use 'syscall', not 'int 0x80'.
  mov   eax, 60
  xor   edi, edi
  syscall
48
Programming with NASM / Re: Printing numbers with stack as variable
« Last post by andyz74 on December 29, 2024, 03:15:01 PM »
Many thanks Frederico!

At least I have a working example of printing by stack. Would have been happy to know, why mine does not work es expected, but I can live with your variante good. :-)

Thanks ! :-)
49
Programming with NASM / Re: Printing numbers with stack as variable
« Last post by fredericopissarra on December 29, 2024, 12:52:05 PM »
For your study:
Code: [Select]
  bits  64
  default rel

  section .rodata

nl:
  db  `\n`

  section .text

  global _start

  align 4
_start:
  sub   rsp,8               ; Align RSP to DQWORD (SysV ABI)

  mov   rdi,12345678        ; # to print.
  call  printUint64Decimal

  ; Print a newline
  mov   eax,1
  mov   edi,eax
  mov   edx,eax
  lea   rsi,[nl]
  syscall

  sub   rsp,8               ; restore RSP

  ; Exit program
  mov   eax,60
  xor   edi,edi
  syscall                   ; This syscall never returns.

; Entry RDI = #
  align 4
printUint64Decimal:
  ; Allocate 24 bytes, realigning RSP to DQWORD (SysV ABI).
  ; We just need 22 bytes in the buffer allocated on the stack.
  sub rsp, 24

  mov r9, rsp
  mov rsi, rsp

  mov r8, 0xcccccccccccccccd      ; 1/10, scaled (0b0.00011001100... rounded and shifted left by 67).

  align 4
.loop:
  mov rax, rdi
  dec rsi

  ; Multiply by scaled 1/10, instead of dividing by 10
  ; This is faster.
  mul r8
  mov rax, rdi
  shr rdx, 3                      ; RDX = quotient

  lea rcx, [rdx+rdx*4]            ; RCX = RDX*10
  add rcx, rcx
  sub rax, rcx                    ; RAX = Dividend - RCX (remainder)
  ; RAX = remainder, RDI = quotient

  ; Store remainder converted to ASCII.
  add al, '0'
  mov [rsi], al

  mov rax, rdi
  mov rdi, rdx

  ; Stay in loop if quotient > 9.
  cmp rax, 9
  ja  .loop

  ; Print the buffer, calculating the size of the string.
  mov eax, 1
  mov rdx, r9
  sub rdx, rsi
  mov edi, eax
  syscall

  add rsp, 24
  ret
50
Programming with NASM / Printing numbers with stack as variable
« Last post by andyz74 on December 29, 2024, 11:34:50 AM »
Hello all, I hope you enjoy winter-holidays! :-)

But now to my problem :
I use Linux 64 bit, and my wish is to print numbers on the screen just by syscall, no extern funtions and no extra variables for storing numbers.  Therefore, I use the common way, push every number to stack to get it later and print.
I know, the syscall to write is with rax=1, rdi=1 to use my screen, rsi as pointer to the adress where my string/number is, and rdx for length of string (in my case 1).
As you can see, I use the stackadress in rsi to get my number, and it works with 8 added or 16 added, but not with the common rsp-adress.
Has anybody of you an idea, what is going wrong ? 

Greetz, and thanks in advance, Andy



Code: [Select]
[bits 64]

SECTION .data
    n: dd 1234

global _start

SECTION .text

    _start:

  mov rax, [n]
  xor rcx, rcx       

.loop:
  mov rbx, 10
  xor rdx, rdx
  div rbx            ; Divide RAX by 10
  add rdx, 30h
  push rdx   ; pop Restzahl auf Stack
  inc rcx
  test rax, rax
  jnz .loop

.loop2:
  mov rax, 1         ; Write system call
  mov rdi, 1         ; STDOUT
  xor rsi, rsi
  mov r10, rsp
  add r10, 0 ; change offset to be read in stack 0, 8 or 16
  mov rsi, r10
  pop r12
  mov rdx, 1 ; ein Zeichen schreiben.
  push rcx
  syscall
  pop rcx
  dec rcx
  test rcx, rcx
  jnz .loop2


   mov rax, 1
   mov rbx, 0
   int 0x80


Pages: 1 ... 3 4 [5] 6 7 ... 10