News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

dwtoa x64

Started by dusty, February 01, 2013, 10:35:08 AM

Previous topic - Next topic

dusty

trying to convert this to x64, the code runs fine until I return to the c++ calling functiion. I get an unhandled exception error. I have a hunch it's a stacck/memory problem

;dwtoa is a MASM32 routine
; void dwto64(int dwValue, char* lpBuffer) C++ calling function
;                   rcx            rdx
; dwvalue 4 byte int, lpBuffer 8 byte ptr

.data

.code
align 16
dwtoa64 proc public
    push rax
    push rbx
    push rsi
    push rdi
   
    mov eax, ecx               ;dwValue
   ;cdq
    mov dword ptr[edi], edx            ;[lpBuffer]

    test eax,eax
    jnz sign

  zero:
    mov word ptr [edi],30h
    jmp dtaexit

  sign:
    jns pos
    mov byte ptr [edi],'-'
    neg eax
    add edi, 1

  pos:
    mov ecx, 3435973837
    mov esi, edi

loop1:
      mov ebx,eax
      mul ecx
      shr edx, 3
      mov eax,edx
      lea edx,[edx*4+edx]
      add edx,edx
      sub ebx,edx
      add bl,'0'
      mov [edi],bl
      add edi, 1
      cmp eax, 0
      jg loop1

    mov byte ptr [edi], 0       ; terminate the string

    ; We now have all the digits, but in reverse order.

loop2:
      sub edi, 1
      mov al, [esi]
      mov ah, [edi]
      mov [edi], al
      mov [esi], ah
      add esi, 1
      cmp edi, esi
      jg loop2
   
  dtaexit:

    pop rdi
    pop rsi
    pop rbx   
    pop rax   

    ret 

dwtoa64 endp
end

frktons

Better to post this thread in the x64 programming subforum.
There are only two days a year when you can't do anything: one is called yesterday, the other is called tomorrow, so today is the right day to love, believe, do and, above all, live.

Dalai Lama

dedndave

in 64-bit, addresses are 64 bits wide   :P
mov dword ptr[edi], edx            ;[lpBuffer]
mov rdi, rdx            ;[lpBuffer]

    mov word ptr [edi],30h
    mov word ptr [rdi],30h

and so on

dedndave

you might consider passing the string pointer in RCX
then - you can use that register to reference the characters without changing


qWord

mov dword ptr[edi], edxshould be
mov rdi, rdx

align 16
dwtoa64 proc
    push rax
    push rbx
    push rsi
    push rdi
   
    mov eax, ecx               ;dwValue
    mov rdi, rdx            ;[lpBuffer]

    test eax,eax
    jnz sign

  zero:
    mov word ptr [rdi],30h
    jmp dtaexit

  sign:
    jns pos
    mov byte ptr [rdi],'-'
    neg eax
    add rdi, 1

  pos:
    mov ecx, 3435973837
    mov rsi, rdi

loop1:
      mov ebx,eax
      mul ecx
      shr edx, 3
      mov eax,edx
      lea edx,[edx*4+edx]
      add edx,edx
      sub ebx,edx
      add bl,'0'
      mov [rdi],bl
      add rdi, 1
      cmp eax, 0
      jg loop1

    mov byte ptr [rdi], 0       ; terminate the string

    ; We now have all the digits, but in reverse order.

loop2:
      sub edi, 1
      mov al, [rsi]
      mov ah, [edi]
      mov [edi], al
      mov [rsi], ah
      add rsi, 1
      cmp rdi, rsi
      jg loop2
   
  dtaexit:

    pop rdi
    pop rsi
    pop rbx   
    pop rax   

    ret 

dwtoa64 endp
MREAL macros - when you need floating point arithmetic while assembling!

dusty

I got it to work

;dwtoa is a MASM32 routine
; void dwto64(int dwValue, char lpBuffer[]) C++ calling function
;                   rcx            rdx
; dwvalue 4 byte int, lpBuffer 8 byte ptr

.data

.code
align 16
dwtoa64 proc public
   
    push rbp
    mov rbp, rsp
   
    push rax
    push rbx
    push rsi
    push rdi
   
   
    mov eax, ecx     ; dwValue
    mov edi, edx     ;[lpBuffer]

    test eax,eax
    jnz sign

  zero:
    mov word ptr [edi],30h
    jmp dtaexit

  sign:
    jns pos
    mov byte ptr [edi],'-'
    neg eax
    add edi, 1

  pos:
    mov ecx, 3435973837
    mov esi, edi

loop1:
      mov ebx,eax
      mul ecx
      shr edx, 3
      mov eax,edx
      lea edx,[edx*4+edx]
      add edx,edx
      sub ebx,edx
      add bl,'0'
      mov [edi],bl
      add edi, 1
      cmp eax, 0
      jg loop1
   
    mov byte ptr [edi], 0       ; terminate the string

    ; We now have all the digits, but in reverse order.

loop2:
      sub edi, 1
      mov al, [esi]
      mov ah, [edi]
      mov [edi], al
      mov [esi], ah
      add esi, 1
      cmp edi, esi
      jg loop2

  dtaexit:
   
      pop rdi
      pop rsi
      pop rbx
      pop rax   
   
      mov rsp, rbp
      pop rbp

    ret 

dwtoa64 endp
end


jj2007

The bold parts look a bit odd - are you sure you need them? Does it crash if you take them away?

dusty

jj2007;
Yes it will crash. I'm using vs2010, mix c++/masm. I had to do that to order to restore my base pointer, which was causing the crash. For some reason calling it from c++ with  void dwtoa64(int num, char* charnum) caused a problem as well, I have not solved that problem yet. It works fine if I call it from c++ void dwtoa64(int num, char charnum[]). but no big deal as I see it ?

japheth

Quote from: dusty on February 03, 2013, 04:40:33 AM
I got it to work

It works, as long as the program and its data is located in the first 4 GB of the address space. To ensure this to be ALWAYS the case you'll have to add linker option /LARGEADDRESSAWARE:NO - or, way better, adjust your routine so it will work with any address ( see qword's post ).

jj2007

Quote from: dusty on February 03, 2013, 04:53:02 AM
jj2007;
Yes it will crash. I'm using vs2010, mix c++/masm. I had to do that to order to restore my base pointer, which was causing the crash.

Apologies if that is a stupid question: Why do you have to restore your base pointer? Where do you use it in the code above?

@japheth: Is that a backdoor entry to the x32 ABI?
What I am wondering is whether /LARGEADDRESSAWARE:NO just limits the module entry point to low addresses; and if so, if a x32 app can still access large addresses by using reg64s.

dusty

If I don't restore my base point it hangs at ret, when I return to c++ calling function the return address is hosed?


private: System::Void test2_Click(System::Object^  sender, System::EventArgs^  e)
{
      dgv->Rows->Clear();
      dgv->RowCount = 50;
      int inum = 1234567890;
      char cnum[17];
      dwtoa64(inum, cnum);
      String ^snum = gcnew String(cnum);
      dgv->Rows[1]->Cells[0]->Value = snum;
}

jj2007

Quote from: dusty on February 03, 2013, 06:17:17 AM
If I don't restore my base point it hangs at ret...

In the code you posted, rbp is not used at all, except for the bold part at top and bottom. They could be omitted, so that rbp gets never touched.

dusty

jj2007

Your'e right......I must have had somethng else in there causing the problem. I had made the  changes esi[rdi] and edi[rdi] but that didn't help, but it does now. I got rid the rbp as you suggested and it all works as it should.
thanks for the tips and your help  :P :P :greenclp: