我正在尝试将一个结构从(x86)汇编程序传递给堆栈上的 Ada。我已经能够在 C 中成功地使用这种模式来接受将从程序集传递的大量参数包装在一个结构中,我想知道这是否会在 Ada 中以类似的方式工作。
这是一个(人为的,最小的)示例:
当我这样做时,调试被调用者显示传递的记录包含未初始化的数据。尽管有导出指令,但 Ada 似乎对 C 调用约定的解释不同。RM 包含有关将结构从 Ada 传递到 C 的信息,表示它将自动将记录作为指针类型传递,但反过来似乎并不成立。如果您接受单一access
类型,它将简单地填充堆栈上的第一个值,正如人们对 cdecl 所期望的那样。
(请原谅任何小错误,这不是我的实际代码。)
#####################################################################
# Caller
#
# This pushes the values onto the stack and calls the Ada function
#####################################################################
.global __example_function
.type __example_function, @function
__example_function:
push $1
push $2
push $3
push $4
call accepts_struct
ret
----------------------------------------------------------------------------
-- Accepts_Struct
--
-- Purpose:
-- Attempts to accept arguments pass on the stack as a struct.
----------------------------------------------------------------------------
procedure Accepts_Struct (
Struct : Struct_Passed_On_Stack
)
with Export,
Convention => C,
External_Name => "accepts_struct";
----------------------------------------------------------------------------
-- Ideally the four variables passed on the stack would be accepted as
-- the values of this struct.
----------------------------------------------------------------------------
type Struct_Passed_On_Stack is
record
A : Unsigned_32;
B : Unsigned_32;
C : Unsigned_32;
D : Unsigned_32;
end record
with Convention => C;
另一方面,这工作得很好:
procedure Accepts_Struct (
A : Unsigned_32;
B : Unsigned_32;
C : Unsigned_32;
D : Unsigned_32
)
with Export,
Convention => C,
External_Name => "accepts_struct";
在这个最小的情况下,这没什么大不了的,但如果我传递 16 个或更多变量,它会变得有点繁重。如果您想知道我为什么要这样做,它是一个异常处理程序,处理器会自动将变量传递到堆栈以显示寄存器状态。
在这里的任何帮助将不胜感激。