News:

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

Main Menu

No XMM register changes

Started by Orzel94, January 21, 2017, 05:54:10 AM

Previous topic - Next topic

TWell

My second code example is C code, not C++. Compile it as C source (*.c).

Orzel94

so again i've got

Error LNK2019 unresolved external symbol _aproxC@32 referenced in function _main test 2 C:\Users\Mateusz\documents\visual studio 2015\Projects\test 2\test 2\Source.obj 1
Error LNK2019 unresolved external symbol _aproxASM@40 referenced in function _main test 2 C:\Users\Mateusz\documents\visual studio 2015\Projects\test 2\test 2\Source.obj 1

first time it was caused by lack of libMain part but now I have it in ASM (but in C++ dll is error too)

jj2007

Try building it without a def file but with aproxASM proc syscall export p_real: REAL8, ...

hutch--

Orzel94,

Just make sure you write the correct prototypes for your C code calling either object modules written in assembler OR a DLL written in assembler. 32 bit MASM supports both STDCALL and C calling conventions, make sure you get this right and look up your compiler reference for "extern c" for the prototypes. In 64 bit the calling convention is FASTCALL and you have to get this right.

coder

I am confused. I thought C returns to ST(0) for 32-bit floaty things.

TWell

#20
I am a bit confused :(

ml.exe -FeaproxASM.dll aproxASM.asm -link -dll -export:aproxASM=_aproxASM@40
cl.exe -Gz -GS- -MD -FeaproxC.dll aproxC.c -link -dll -export:aproxC=_aproxC@32
cl.exe -GS- -MD aprox_test.c


aprox_test.obj : error LNK2019: unresolved external symbol _aproxC@32 referenced in function _main
aprox_test.obj : error LNK2019: unresolved external symbol _aproxASM@40 referenced in function _main
aprox_test.exe : fatal error LNK1120: 2 unresolved externals


Even after reading these:
EXPORTS
https://msdn.microsoft.com/en-us/library/aa278935(v=vs.60).aspx
-export
https://msdn.microsoft.com/en-us/library/aa235424(v=vs.60).aspx

polink.exe works as documented.

EDIT:
EXPORTS
https://msdn.microsoft.com/en-us/library/hyx1zcd3(v=vs.140).aspx

This syntax should be still validentryname[=internalname] [@ordinal [NONAME]] [[PRIVATE] | [DATA]]

EDIT:
With polib.exe or def2lib.exe we can have correct libs.LIBRARY aproxC.dll
EXPORTS
;aproxC=_aproxC@32
"_aproxC@32"
LIBRARY aproxASM.dll
EXPORTS
;aproxASM=_aproxASM@40
"_aproxASM@40"


jj2007

Quote from: coder on January 22, 2017, 03:56:43 PM
I am confused. I thought C returns to ST(0) for 32-bit floaty things.

That's correct. In assembly, you must do it by hand. Here are two options:
push eax ; return int(eax) in ST(0)
fild dword ptr [esp]
pop eax
ret

sub esp, 8 ; create a REAL8 slot
movlps qword ptr [esp], xmm0   ; move the value to be returned from xmm0 to the stack
fld REAL8 ptr [esp]
add esp, 8
ret


As to building Mateusz' dll code, see reply #17. It works.

Orzel94

I have now completely mess in mind...
Without .def file i can only compile it to .exe file not .dll

even when I compile asm code which do simply nothing but returnig integer value

;-------------------------------------------------------------------------
.686
.MMX
.XMM
.MODEL FLAT, STDCALL
OPTION CASEMAP:NONE
.DATA
circle DD 360
.CODE
LibMain proc instance:DWORD, reason:DWORD, unused:DWORD
  mov eax, 1
  ret
LibMain endp
aproxASM proc p_real: REAL8, p_imaginary: REAL8, c_real:REAL8, c_imaginary:REAL8, four:REAL8
MOV eax,12
ret
aproxASM endp

end LibMain

or like jj2007 mentioned
;-------------------------------------------------------------------------
.686
.MMX
.XMM
.MODEL FLAT, STDCALL
OPTION CASEMAP:NONE
.DATA
circle DD 360
.CODE
LibMain proc instance:DWORD, reason:DWORD, unused:DWORD
  mov eax, 1
  ret
LibMain endp
aproxASM proc p_real: REAL8, p_imaginary: REAL8, c_real:REAL8, c_imaginary:REAL8, four:REAL8
MOV eax,12
push eax ; return int(eax) in ST(0)
fild dword ptr [esp]
pop eax
ret
aproxASM endp

end LibMain


I've got stack balance error

TWell

You function return int.
jj2007 comment was for float, so not for your code, if that return int.

BTW
use eax in your code as it is free register, so return value is already in right place.

That syscall tip works to decoration issue, but read this:
http://masm32.com/board/index.php?topic=3640.msg38361#msg38361

Otherwise you need some export manipulation for undecorated name.


jj2007

It seems I got a solution (no def file needed):

aproxASM proc c export p_real: REAL8, p_imaginary: REAL8, c_real:REAL8, c_imaginary:REAL8, four:REAL8
  ...
  ret

Attached testbed needs MasmBasic to build, but you can test the DLL with your C compiler as well.

@OP: It would help if you provided a usage example, i.e. five float arguments, and the expected result.

CheckMateusz.exe loads the DLL and executes aproxASM with 5 dummy args, it returns 123456789 and checks if the stack is balanced.

In case you want to test the build:
- create an empty TmpDllEx.def in the source folder, and write-protect it (sorry, this is a hack, I know)
- open Mateusz.asc in RichMasm
- hit F6 to a) build the DLL and b) run CheckMateusz.exe to test it

It works also with stdcall, see second attachment.

TWell

test program in C for dll#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>

//int aproxASM(double p_real, double p_imaginary, double c_real, double c_imaginary, double four);
typedef int (APROXASM)(double p_real, double p_imaginary, double c_real, double c_imaginary, double four);
typedef APROXASM*PAPROXASM;

int __cdecl main(void)
{
double p_real = -1.5;
double p_imaginary = -1.5;
double c_real = 0.65;
double c_imaginary = -0.03;
double four = 4.0;
HANDLE hLib;
static PAPROXASM aproxASM;
hLib = LoadLibrary("Mateusz.dll");
aproxASM = (PAPROXASM)GetProcAddress(hLib, "aproxASM");

int aa = aproxASM(p_real, p_imaginary, c_real, c_imaginary, four);
printf("aa=%d\n", aa);

return 0;
}

Orzel94

YES!
it's working! (jj2007 solution) it's returning values! It's returning 360 instead of 1 but It does not matter it's working afer 3 days of fighting with it!

So now it's look like this
when I compile it with VS it's working and returning value to C#  and I know that VS dubbuger has SH** value because it show no changes in XMM registersand it shows that in EAX is 168 but it returns 360 (when I put only one instruction MOV eax,12 it returns 12 so I thing its debugger showing sth wrong)
OllyDGB some assembler code but it completly don't look like mine (matter if I compile it in debug mode?)

when I compile the same code by QEditor using Makeit.bat  it don't work with C# (exception is thrown) but in OllyDGB I see my code but I don't know how tu put parameters tu the procedure when using Call DLL export (it says only integer values can be put)

So I have pretty working code but I have no idea how tu debug it XD

jj2007

Quote from: Orzel94 on January 23, 2017, 01:12:34 AMin EAX is 168 but it returns 360

168 is the hex representation of 360 decimal. Olly shows hex most of the time, except if the values have a dot, like 123.

If you want symbols in the debugger:
; OPT_Symbols   1 ; for RichMasm, somewhere in the source

Otherwise, add
/Zi /Zf to the assembler,
/debug to the linker commandline

There are not many symbols to see in the debugger, but if the symbols work properly, you will see for example:72E81095          660F2FE2          comisd xmm4, xmm2
72E81099         77 C7             ja short 72E81062
72E8109B          B8 68010000       mov eax, 168
72E810A0          391D 0040E872     cmp [circle], ebx   ; <<<<<<<<<<<<<<<<<<<<<<<<
72E810A6         7F BA             jg short 72E81062
72E810A8          8BC3              mov eax, ebx
72E810AA          5B                pop ebx
72E810AB          5D                pop ebp
72E810AC          C3                retn


Note the mov eax, 168 - it's 360, of course. Now that the building and testing process is OK, maybe it's time to look at the code again? ;-)
aproxASM_stdcall proc stdcall export uses ebx p_real: REAL8, p_imaginary: REAL8, c_real:REAL8, c_imaginary:REAL8, four:REAL8
  xor eax, eax ; zero
  movlpd xmm4, four
  movlpd xmm0, p_real
  movlpd xmm1, p_imaginary

doloop: ; real_part
  inc eax ; loop indexer
  vmulsd xmm2, xmm0, xmm0
  vmulsd xmm3, xmm1, xmm1
  subsd xmm2, xmm3
  addsd xmm2, c_real

  ; imaginary_part
  vmulsd xmm3, xmm0, xmm1
  addsd xmm3, xmm3
  addsd xmm3, c_imaginary

  movsd xmm0, xmm2
  movsd xmm1, xmm3


  ; complexMod
  vmulsd xmm2, xmm0, xmm0
  vmulsd xmm3, xmm1, xmm1
  addsd xmm2, xmm3

  ; while (modulo < 4 && i < 360);
  comisd xmm4, xmm2
  ja doloop
  cmp circle, 360 ; makes no sense at all, circle is DD 360!
  jg doloop
  ret
aproxASM_stdcall endp

Orzel94

here it's how the code looks now
;-------------------------------------------------------------------------
.686
.MMX
.XMM

.MODEL FLAT, STDCALL
OPTION CASEMAP:NONE


.DATA
circle DD 360
.CODE
LibMain proc  instance:DWORD, reason:DWORD, unused:DWORD
  mov eax, 1
  ret
LibMain endp
;-------------------------------------------------------------------------
aproxASM proc c export p_real: REAL8, p_imaginary: REAL8, c_real:REAL8, c_imaginary:REAL8, four:REAL8
MOV ecx,0
MOVLPD XMM4,[four]
MOVLPD XMM0,[p_real]
MOVLPD XMM1,[p_imaginary]
do:

;real_part
VMULSD XMM2,XMM0,XMM0
VMULSD XMM3,XMM1,XMM1
SUBSD XMM2,XMM3
ADDSD XMM2,c_real

;imaginary_part
VMULSD XMM3,XMM0,XMM1
ADDSD XMM3,XMM3
ADDSD XMM3,[c_imaginary]

MOVSD XMM0,XMM2
MOVSD XMM1,XMM3

INC ecx ;loop indexer

;complexMod
VMULSD XMM2,XMM0,XMM0
VMULSD XMM3,XMM1,XMM1
ADDSD XMM2,XMM3

;while (modulo < 4 && i < 360);
COMISD XMM4,XMM2
JG second
JMP done
;MOV eax,360
second:
CMP circle,ecx
JG do
done:
MOV eax,ecx
;MOV eax,12


ret
aproxASM endp

end LibMain

this cmp ccircle,360 disapeared earlier
I fix issue with "while" implementation and now its working excatly as code in C (only difference is result i ASM == result in C + ~10 or + ~11 (I thing)  I don't know why yet but the only thing it changes it move a little bit color in HSV (instead of red is more orange (i wrote 2D fractal generator)) so I can say to teacher that I have planned it XD )

So thank you very much ;)