-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HL-ZASM Passing and returning stack objects. #4
Comments
That explains a lot, thanks for figuring it out. When I asked @PhoenixBlack to add structs, they seemed to be a bit wonky, but I was not able to actually figure it out. It appears it is just not able to determine the size of structs correctly. You might want to try to pass them as pointers, that might work. |
#pragma set OutputFinalListing true
struct vec2
{
float x;
float y;
};
void distance(vec2 v) {
v.x + v.y;
}
vec2 v;
v.x = 3;
v.y = 4;
distance(v); Output: distance:
// distance(v)
0 enter -0
__1:
3 rstack EAX,EBP:4
7 rstack EBX,EBP:3
11 add EBX,EAX
// v.x+v.y
13 sstack EBP:3,EBX
__0:
17 leave
18 ret
v:
19 alloc 2
21 mov EAX,0
24 add EAX,19
// v.x=3
27 mov #EAX,3
30 mov EAX,1
33 add EAX,19
// v.y=4
36 mov #EAX,4
// distance arg wiremod/wire#1 (vec2 v)
39 push wiremod/wire#19
42 mov ECX,1
// distance(...)
45 call 0
48 add ESP,1 |
#pragma set OutputFinalListing true
struct vec2
{
float x;
float y;
};
vec2 rotate(vec2 u)
{
vec2 v;
v.x = -u.y;
v.y = u.x;
};
vec2 u;
vec2 v;
u.x = 3;
u.y = 4;
v = rotate(u); rotate:
; rotate(u)
0 enter 2
__1:
3 rstack EAX,EBP:4
; v.x=-u.y
7 sstack EBP:-2,EAX
11 rstack EAX,EBP:3
; v.y=u.x
15 sstack EBP:-1,EAX
__0:
19 leave
20 ret
u:
21 alloc 2
v:
23 alloc 2
25 mov EAX,0
28 add EAX,21
; u.x=3
31 mov #EAX,3
34 mov EAX,1
37 add EAX,21
; u.y=4
40 mov #EAX,4
43 push wiremod/wire#21
46 mov ECX,1
; rotate(...)
49 call 0
52 add ESP,1
; v=rotate(u)
55 mov wiremod/wire#23,EAX |
Incorrect code is generated for passing structs and arrays on the stack to functions and for returning them. In the case of passing, the caller just passes the first byte of the array or struct. The callee code is actually generated correctly and would be able to receive the object if it were passed correctly. In the case of returning, the first element of the object is stored in eax and no copying is done.
If the compiler was never meant to have these features, it should at least throw an error rather than passing/returning the first byte of the object.
EDIT: Seems like arrays of structs aren't indexed correctly (index isn't aligned to the size of the struct) and reading arrays of structs won't copy structs onto the stack either.
The text was updated successfully, but these errors were encountered: