Segfault trying to pass more than 6 arguments to a function (x86_64 ASM)
Hi everybody.
I'm still working on learning ASM, you helped me before so maybe you can help me out again. I am trying to call a C function from my ASM code. The function is part of SDL. I have used this function before in C so I know what I am supposed to do with it, but I can't figure out how to call it the same way in ASM. The problem is that the function takes 8 arguments. Since I am on x86_64 Linux, that means I have to pass the first 6 in registers and the last two on the stack. I didn't think this would be a big deal, but I just can't get it to work. To compound the issue, I am also trying to extract data to pass to this function from a structure which was allocated by SDL. So I created these structures (YASM Syntax): Code:
struc SDL_PixelFormat I then initialize SDL as I did before and then call the function like this: Code:
CreateSurface: Can anybody see what it is? Thanks! |
Quote:
If you have ANY doubt about the ABI details for calling some function, code the call in C, then look at the asm code created by the C compiler. Hopefully you know how to use the -S option to gcc and/or one of the many other ways to see the compiler output as asm code. Edit: The above is still an important tool you should use when you have any ABI doubts, but after reading your whole post, I think the problem is more likely to be in the SDL_PixelFormat struct rather than in the mechanism of passing parameters to that function. |
Quote:
|
Quote:
I can't think of anything fmt might be that makes this use of fmt consistent with your later use of fmt. |
Quote:
|
Quote:
fmt resq 1 It's a pointer. screen is an instance of SDL_Surface, which is a structure that contains a pointer to SDL_PixelFormat. It gets allocated and initialized by SDL in SDL_SetVideoMode. I set fmt to the address of the SDL_PixelFormat structure which is inside the structure and then try to access the members of the SDL_PixelFormat structure. That's what I was trying to do. |
Quote:
Assembler doesn't work like that at all. Forget fmt. You need the pointer in a register and you had (see below) the pointer in a register. I don't know yasm syntax exactly, but instead of Code:
mov rcx,fmt+SDL_PixelFormat.BitsPerPixel Code:
mov rcx,[R11+SDL_PixelFormat.BitsPerPixel] Code:
mov rcx,SDL_PixelFormat.BitsPerPixel[R11] To use a pointer in assembler, the pointer must be in a register and you must specify a valid addressing mode that combines that register with the desired offset. I also looked up SDL_PixelFormat with google and I see your asm version of that struct does not match the standard layout. Also, setting up R11 before an unrelated call doesn't work, since the unrelated call clobbers that register. Also, your syntax was wrong again in: Code:
mov r11,screen+SDL_Surface.format If you were using gas syntax, it would be a lot easier to compare your own efforts with the output of gcc. If you were using gas syntax, more experts in this forum could help you. Yasm may be a great tool for those who learned asm on Windows and don't want to relearn the syntax. But obviously you don't know yasm syntax yet. |
Quote:
my code looks like this: Code:
CreateSurface: I think I must not be since the program segfaults at ret. |
Instead of
Code:
pop rbp Code:
leave In case you missed my last edits to the earlier post, your "screen+SDL_Surface.format" was wrong. What is correct depends on how screen was defined and initialized. Also I'm pretty sure your declaration of SDL_PixelFormat was wrong, both alignment issues and having the wrong size for Amask etc. There are some details I'm not 100% certain of: In 64-bit mode, I believe a push from memory cannot read just a 32-bit value. I know it must write a 64-bit value. That called function expects a 32-bit value on the stack and the next 32-bits wasted. If Amask had been properly declared as 32 bits, I would have used Code:
mov eax, [r11+SDL_PixelFormat.Amask] Code:
push qword [r11+SDL_PixelFormat.Amask] |
You have a choice of style (which sometimes impacts performance):
Code:
sub rsp, 24 Code:
push rbp |
All times are GMT -5. The time now is 07:08 AM. |