Ik heb een programma onder x64 gecompileerd waar het bekende '1% van de code, 99% van de tijd' paradigma op invloed is. Als ik zo de assembly bekijk zijn er een aantal verbeteringen mogelijk (in het bijzonder, in de loop gebruikt msvc een aantal vmovaps welke totaal onnodig zijn, alles past in de registers).
Ik gebruik msvc11 (2012) x64. Deze ondersteunt geen inline assembly. Volgens deze http://www.sciencezero.or...nctions_in_Visual_C%2B%2B tutorial kan je met yasm een functie in asm definiëren welke je vervolgens kan aanroepen met een C call. Een probleem is dat deze tutorial (en elke andere die ik kan vinden) er van uit gaat dat je Microsoft IDE's gebruikt.
C++ code:
Assembly:
.. wat gewoon een ctrl-c ctrl-v stuk code is.
Met YASM heb ik deze assembly gecompilered met deze command line:
Probleem: mijn compilers willen deze .obj file niet linken. MVSC geeft:
MinGW (4.4 en 4.8.1 x64) geeft:
Het vreemde is dat wanneer ik MSVC compileer met de /VERBOSE switch, calc.obj niet voorkomt in de lijst met assembly's die hij doorzoekt. Het lijkt erop dat msvc mijn .obj negeert. Als ik de .obj dubbel in de command line gooi geeft hij wel netjes een warning dat het object meer dan eens is gespecificeerd.
Wie weet de oplossing?
Ik gebruik msvc11 (2012) x64. Deze ondersteunt geen inline assembly. Volgens deze http://www.sciencezero.or...nctions_in_Visual_C%2B%2B tutorial kan je met yasm een functie in asm definiëren welke je vervolgens kan aanroepen met een C call. Een probleem is dat deze tutorial (en elke andere die ik kan vinden) er van uit gaat dat je Microsoft IDE's gebruikt.
C++ code:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
| extern "C" { int calc (int a, int b, int c, char d, char* e, float fa, float fb); } int main() { char q = 'q'; calc( 1, 2, 3, 'a', &q, 1.0, -1.0 ); return 0; } |
Assembly:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| PROC_FRAME calc
db 0x48 ; emit a REX prefix to enable hot-patching
push rbp ; save prospective frame pointer
[pushreg rbp] ; create unwind data for this rbp register push
sub rsp,0x40 ; allocate stack space
[allocstack 0x40] ; create unwind data for this stack allocation
lea rbp,[rsp+0x20] ; assign the frame pointer with a bias of 32
[setframe rbp,0x20] ; create unwind data for a frame register in rbp
movdqa [rbp],xmm7 ; save a non-volatile XMM register
[savexmm128 xmm7, 0x20] ; create unwind data for an XMM register save
mov [rbp+0x18],rsi ; save rsi
[savereg rsi,0x38] ; create unwind data for a save of rsi
mov [rsp+0x10],rdi ; save rdi
[savereg rdi, 0x10] ; create unwind data for a save of rdi
[endprolog]
movdqa xmm7,[rbp] ; restore the registers that weren't saved
mov rsi,[rbp+0x18] ; with a push; this is not part of the
mov rdi,[rbp-0x10] ; official epilog
lea rsp,[rbp-0x20] ; This is the official epilog
pop rbp
ret
ENDPROC_FRAME |
.. wat gewoon een ctrl-c ctrl-v stuk code is.
Met YASM heb ik deze assembly gecompilered met deze command line:
code:
1
| -Xvc -f x64 %{sourceDir}/calc.asm -o calc.obj |
Probleem: mijn compilers willen deze .obj file niet linken. MVSC geeft:
code:
1
| main.obj:-1: error: LNK2019: unresolved external symbol calc referenced in function main |
MinGW (4.4 en 4.8.1 x64) geeft:
code:
1
| C:\blaah blah\calc.obj:-1: error: file not recognized: File format not recognized |
Het vreemde is dat wanneer ik MSVC compileer met de /VERBOSE switch, calc.obj niet voorkomt in de lijst met assembly's die hij doorzoekt. Het lijkt erop dat msvc mijn .obj negeert. Als ik de .obj dubbel in de command line gooi geeft hij wel netjes een warning dat het object meer dan eens is gespecificeerd.
Wie weet de oplossing?
