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
Better to post this thread in the x64 programming subforum.
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
you might consider passing the string pointer in RCX
then - you can use that register to reference the characters without changing
mov dword ptr[edi], edx
should 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
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
The bold parts look a bit odd - are you sure you need them? Does it crash if you take them away?
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 ?
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 ).
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 (http://lwn.net/Articles/456731/)?
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.
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;
}
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.
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: