Overview of Cross-Language Array Transfer
In mixed programming, transferring array data between C/C++ and Assembly Language (HLA) is a common requirement. The key is to understand the differences in how different languages handle arrays and to ensure the correct memory layout and access methods.
Basics of Array Transfer between C/C++ and HLA
1. Array Transfer Mechanism
In C/C++, arrays are always passed by reference (i.e., pointers) rather than by value. Therefore, in HLA code, array parameters must be handled accordingly using reference passing.
2. Memory Layout of Multidimensional Arrays
Multidimensional arrays in C/C++ use row-major storage order. This means that all elements of the first row are stored in memory first, followed by the second row, and so on.
Code Example Analysis
Declaration on the C/C++ Side
int CArray[128][4];
extern void PassedArray(int array[128][4]);
Corresponding Declaration on the HLA Side
type
CArray: int32[128,4];
procedure PassedArray(var ary: CArray); @external;
Key Points Explanation
- Type Matching: The
<span>int32</span>in HLA corresponds to the<span>int</span>type in C/C++ (assuming a 32-bit system) - Dimension Declaration:
<span>[128,4]</span>corresponds to the dimension declaration of<span>[128][4]</span> - Reference Passing: HLA uses
<span>var</span>parameters to ensure reference passing, consistent with the array passing method in C/C++
Accessing Multidimensional Array Elements
Since C/C++ uses row-major order, accessing elements in HLA requires maintaining the same calculation method. For the array <span>array[y][x]</span>:
- In C/C++, the address calculation is:
<span>base_address + (y * row_size + x) * element_size</span> - In HLA, the same calculation order must be maintained
Access Example in HLA
procedure AccessArrayElement(var arr: CArray; y: int32; x: int32): int32;
begin AccessArrayElement;
// Calculate element address (row-major)
mov(y, ebx);
imul(4, ebx); // 4 elements per row
add(x, ebx); // Add column index
mov(arr[ebx*4], eax); // Read element (int32=4 bytes)
// Return value in eax
end AccessArrayElement;
Practical Application Example
C/C++ Calling HLA Function
#include <stdio.h>
extern void HLAFunction(int matrix[128][4]);
int main() {
int myArray[128][4];
// Initialize array
for(int y = 0; y < 128; y++) {
for(int x = 0; x < 4; x++) {
myArray[y][x] = y * 10 + x;
}
}
// Call HLA function
HLAFunction(myArray);
return 0;
}
HLA Implementation
program DemoHLACArray;
#include("stdlib.hhf")
type
CArray: int32[128, 4];
procedure HLAFunction(var matrix: CArray); @external;
procedure HLAFunction(var matrix: CArray);
begin HLAFunction;
// Example of accessing array elements
mov(0, ebx); // Row index
mov(2, ecx); // Column index
// Calculate address: ebx = (row * 4 + col) * 4
mov(ebx, eax);
shl(2, eax); // Multiply by 4 (4 elements per row)
add(ecx, eax);
mov(matrix[eax*4], eax); // Read element
stdout.put("matrix[0][2] = ", eax, nl);
end HLAFunction;
begin DemoHLACArray;
end DemoHLACArray;
Considerations
- Memory Alignment: Ensure that the alignment of arrays is consistent in both languages
- Index Range: Both C/C++ and HLA should adhere to the declared array boundaries
- Calling Conventions: Ensure that the function calling conventions are consistent (e.g., cdecl, stdcall, etc.)
- Data Type Size: Ensure that types like int32 have the same size in both environments
By following these principles, the correct transfer and access of array data between C/C++ and HLA can be ensured.