Author Topic: dd to dq conversion  (Read 4131 times)

Joao Batista

  • Guest
dd to dq conversion
« on: December 20, 2012, 09:49:46 AM »
Hi! i'm back again :P

This time i just need help with a single line of code

i have a dq variable and i need to cast it to a dd or a register

i need this:
Code: [Select]
MOV ebx,offset dq_array
MOV __pos, __AUX

to be something like this:
Code: [Select]
MOV ebx,offset dq_array
mov ecx , __AUX
MOV __pos, ecx

dedndave

  • Member
  • *****
  • Posts: 8825
  • Still using Abacus 2.0
    • DednDave
Re: dd to dq conversion
« Reply #1 on: December 20, 2012, 09:59:04 AM »
well - there are a couple ways to solve this

one way is to declare the array as dword type
i think this is what many of us do to save some typing   :P
on a 32-bit machine, we don't have a lot of great ways to handle 64-bit values
unless they are used with FPU, MMX, or SSE instructions

another way is to use a size override
the assembler regards the label as a qword type, and spits out errors if you try to address it otherwise
this is to help catch possible errors in your code
but, you can use something like this...
Code: [Select]
mov ecx , dword ptr __AUX
MOV dword ptr __pos, ecx
there is probably a way to use the ASSUME directive, as well - never tried that

hopefully, __AUX and __pos are not structure members - if they are, i'd have to modify the above code

in the old days, i used to do something like this so i could access 16-bit and 8-bit items in a mixed fashion
Code: [Select]
NameW LABEL WORD
NameL db ?
NameH db ?
you can access the 3 different names to get different pieces
nowdays, i would be more inclined to make a structure if i wanted items to be "tied" together
and - i would use size override operators

Joao Batista

  • Guest
Re: dd to dq conversion
« Reply #2 on: December 20, 2012, 10:43:34 AM »
uhm.. i misstyped.. i wanted to convert a dq variable to a dd variable..
thing is.. im trying to access to a dq array using a dq value as an index. but since i can't use a dq value as an index, i'm trying to convert the dq var to a dd so i can do something like this

Code: [Select]
MOV edx,offset _b ; i get the offset of the dq array
mov ecx , dword ptr ___AUX ; supposed to convert ___AUX (wich is a dq var) to a dd in ecx
MOV dword ptr __pos, ecx
ADD edx, __pos ;i want to add to the offset, ___AUX value
FLD qword ptr [edx] ; so i can access the array at that position

dedndave

  • Member
  • *****
  • Posts: 8825
  • Still using Abacus 2.0
    • DednDave
Re: dd to dq conversion
« Reply #3 on: December 20, 2012, 10:54:25 AM »
you can't use a 64-bit index on a 32-bit machine
at least, not if the index exceeds 32 bits   :P
31 bits, realistically - if you try to create an array larger than 2 GB, you'll have trouble

all the upper bits are probably 0

you can also use

Code: [Select]
FLD qword ptr _b[edx]
not that critical, but notice that the index in EDX is now relative to the base of the array
it is the same thing as

Code: [Select]
FLD qword ptr [_b+edx]

Joao Batista

  • Guest
Re: dd to dq conversion
« Reply #4 on: December 20, 2012, 02:03:23 PM »
Thanks for the help man.. we are having trouble with some stuff we thought was working .. but i THINK your solution with

Code: [Select]
MOV ebx,offset _b
mov ecx , dword ptr ___AUX
MOV dword ptr __pos, ecx
ADD ebx, __pos

worked well :) thanks!

raymond

  • Member
  • **
  • Posts: 236
    • Raymond's page
Re: dd to dq conversion
« Reply #5 on: December 22, 2012, 04:33:47 PM »
Before you go off on a tangent, let's make sure about the meaning of "index" for that dq array.

IF you are trying to convert some code from some HLL, that index could possibly mean the nth member of that array. In such a case, in assembly, you would have to multiply it by 8 to have access to the correct data in that array!
Whenever you assume something, you risk being wrong half the time.
http://www.ray.masmcode.com/

MichaelW

  • Global Moderator
  • Member
  • *****
  • Posts: 1209
Re: dd to dq conversion
« Reply #6 on: December 22, 2012, 07:48:18 PM »
In 32-bit code why is the index a 64-bit value when only the low-order 32 bits are usable? The Microsoft 32-bit compilers can use a 64-bit index variable without a cast, but to do so they add extra instructions and a function call that are not necessary with a cast or a 32-bit index variable. Note that I compiled without optimization, because if I specified /O2 /G6 then the compiler would simply discard everything down to line 13 inclusive, and I did not feel inclined to wrestle with it (and the assembly code would likely have been harder to understand).
Code: [Select]
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
long long a[99];
int main(void)
{
    long long r, x = 0;
    int i = 0;
    r = a[x];         // line 9
    r = a[(int)x];    // line 10
    r = a[0];         // line 11
    r = a[1];         // line 12
    r = a[i];         // line 13
    getch();
    return 0;
}
Code: [Select]
; Listing generated by Microsoft (R) Optimizing Compiler Version 13.10.3077

TITLE test.c
.386P
include listing.inc
if @Version gt 510
.model FLAT
else
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
_DATA SEGMENT DWORD USE32 PUBLIC 'DATA'
_DATA ENDS
CONST SEGMENT DWORD USE32 PUBLIC 'CONST'
CONST ENDS
_BSS SEGMENT DWORD USE32 PUBLIC 'BSS'
_BSS ENDS
$$SYMBOLS SEGMENT BYTE USE32 'DEBSYM'
$$SYMBOLS ENDS
_TLS SEGMENT DWORD USE32 PUBLIC 'TLS'
_TLS ENDS
FLAT GROUP _DATA, CONST, _BSS
ASSUME CS: FLAT, DS: FLAT, SS: FLAT
endif

INCLUDELIB LIBC
INCLUDELIB OLDNAMES

_DATA SEGMENT
COMM _a:QWORD:063H
_DATA ENDS
PUBLIC _main
EXTRN __allmul:NEAR
EXTRN _getch:NEAR
; Function compile flags: /Odt
_TEXT SEGMENT
_r$ = -24 ; size = 8
_i$ = -12 ; size = 4
_x$ = -8 ; size = 8
_main PROC NEAR
; File c:\program files\microsoft visual c++ toolkit 2003\my\qwordarray\test.c
; Line 6
push ebp
mov ebp, esp
sub esp, 24 ; 00000018H
; Line 7
mov DWORD PTR _x$[ebp], 0
mov DWORD PTR _x$[ebp+4], 0
; Line 8
mov DWORD PTR _i$[ebp], 0
; Line 9
push 0
push 8
mov eax, DWORD PTR _x$[ebp+4]
push eax
mov ecx, DWORD PTR _x$[ebp]
push ecx
call __allmul
mov edx, DWORD PTR _a[eax]
mov DWORD PTR _r$[ebp], edx
mov eax, DWORD PTR _a[eax+4]
mov DWORD PTR _r$[ebp+4], eax
; Line 10
mov ecx, DWORD PTR _x$[ebp]
mov edx, DWORD PTR _a[ecx*8]
mov DWORD PTR _r$[ebp], edx
mov eax, DWORD PTR _a[ecx*8+4]
mov DWORD PTR _r$[ebp+4], eax
; Line 11
mov ecx, DWORD PTR _a
mov DWORD PTR _r$[ebp], ecx
mov edx, DWORD PTR _a+4
mov DWORD PTR _r$[ebp+4], edx
; Line 12
mov eax, DWORD PTR _a+8
mov DWORD PTR _r$[ebp], eax
mov ecx, DWORD PTR _a+12
mov DWORD PTR _r$[ebp+4], ecx
; Line 13
mov edx, DWORD PTR _i$[ebp]
mov eax, DWORD PTR _a[edx*8]
mov DWORD PTR _r$[ebp], eax
mov ecx, DWORD PTR _a[edx*8+4]
mov DWORD PTR _r$[ebp+4], ecx
; Line 14
call _getch
; Line 15
xor eax, eax
; Line 16
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END

Well Microsoft, here’s another nice mess you’ve gotten us into.