在 Ada 中将地址拆分并转换为不同的整数
Split and casting address into different integers in Ada
要与特定硬件接口(在本例中为 x86 GDT 的 TSS 条目),需要在内存中使用以下结构:
type UInt32 is mod 2 ** 32;
type UInt16 is mod 2 ** 16;
type UInt8 is mod 2 ** 8;
type TSSEntry is record
Limit : UInt16;
BaseLow16 : UInt16;
BaseMid8 : UInt8;
Flags1 : UInt8;
Flags2 : UInt8;
BaseHigh8 : UInt8;
BaseUpper32 : UInt32;
Reserved : UInt32;
end record;
for TSSEntry use record
Limit at 0 range 0 .. 15;
BaseLow16 at 0 range 16 .. 31;
BaseMid8 at 0 range 32 .. 39;
Flags1 at 0 range 40 .. 47;
Flags2 at 0 range 48 .. 55;
BaseHigh8 at 0 range 56 .. 63;
BaseUpper32 at 0 range 64 .. 95;
Reserved at 0 range 96 .. 127;
end record;
for TSSEntry'Size use 128;
当运行将一些C代码写入Ada时,我运行遇到了几个问题,我在网上找不到很多资源。 C 代码段是:
TSSEntry tss;
void loadTSS(size_t address) {
tss.baseLow16 = (uint16_t)address;
tss.baseMid8 = (uint8_t)(address >> 16);
tss.flags1 = 0b10001001;
tss.flags2 = 0;
tss.baseHigh8 = (uint8_t)(address >> 24);
tss.baseUpper32 = (uint32_t)(address >> 32);
tss.reserved = 0;
}
这是我尝试将其转换为的 Ada 代码运行:
TSS : TSSEntry;
procedure loadTSS (Address : System.Address) is
begin
TSS.BaseLow16 := Address; -- How would I downcast this to fit in the 16 lower bits?
TSS.BaseMid8 := Shift_Right(Address, 16); -- Bitwise ops dont take System.Address + downcast
TSS.Flags1 := 2#10001001#;
TSS.Flags2 := 0;
TSS.BaseHigh8 := Shift_Right(Address, 24); -- Same as above
TSS.BaseUpper32 := Shift_Right(Address, 32); -- Same as above
TSS.Reserved := 0;
end loadTSS;
我怎样才能显示我在代码中突出显示的问题?在这种情况下,初学者是否可以使用任何资源来寻求帮助?提前致谢!
使用包 System.Storage_Elements 中的 To_Integer 函数将地址转换为整数,然后将该整数转换为接口。Unsigned_32 或 Unsigned_64(以哪个为准适当的)以便您可以使用移位操作来提取位域。
除了移位和掩码操作,您当然可以使用除法和“mod”来分离整数,而无需转换为接口类型。
要与特定硬件接口(在本例中为 x86 GDT 的 TSS 条目),需要在内存中使用以下结构:
type UInt32 is mod 2 ** 32;
type UInt16 is mod 2 ** 16;
type UInt8 is mod 2 ** 8;
type TSSEntry is record
Limit : UInt16;
BaseLow16 : UInt16;
BaseMid8 : UInt8;
Flags1 : UInt8;
Flags2 : UInt8;
BaseHigh8 : UInt8;
BaseUpper32 : UInt32;
Reserved : UInt32;
end record;
for TSSEntry use record
Limit at 0 range 0 .. 15;
BaseLow16 at 0 range 16 .. 31;
BaseMid8 at 0 range 32 .. 39;
Flags1 at 0 range 40 .. 47;
Flags2 at 0 range 48 .. 55;
BaseHigh8 at 0 range 56 .. 63;
BaseUpper32 at 0 range 64 .. 95;
Reserved at 0 range 96 .. 127;
end record;
for TSSEntry'Size use 128;
当运行将一些C代码写入Ada时,我运行遇到了几个问题,我在网上找不到很多资源。 C 代码段是:
TSSEntry tss;
void loadTSS(size_t address) {
tss.baseLow16 = (uint16_t)address;
tss.baseMid8 = (uint8_t)(address >> 16);
tss.flags1 = 0b10001001;
tss.flags2 = 0;
tss.baseHigh8 = (uint8_t)(address >> 24);
tss.baseUpper32 = (uint32_t)(address >> 32);
tss.reserved = 0;
}
这是我尝试将其转换为的 Ada 代码运行:
TSS : TSSEntry;
procedure loadTSS (Address : System.Address) is
begin
TSS.BaseLow16 := Address; -- How would I downcast this to fit in the 16 lower bits?
TSS.BaseMid8 := Shift_Right(Address, 16); -- Bitwise ops dont take System.Address + downcast
TSS.Flags1 := 2#10001001#;
TSS.Flags2 := 0;
TSS.BaseHigh8 := Shift_Right(Address, 24); -- Same as above
TSS.BaseUpper32 := Shift_Right(Address, 32); -- Same as above
TSS.Reserved := 0;
end loadTSS;
我怎样才能显示我在代码中突出显示的问题?在这种情况下,初学者是否可以使用任何资源来寻求帮助?提前致谢!
使用包 System.Storage_Elements 中的 To_Integer 函数将地址转换为整数,然后将该整数转换为接口。Unsigned_32 或 Unsigned_64(以哪个为准适当的)以便您可以使用移位操作来提取位域。
除了移位和掩码操作,您当然可以使用除法和“mod”来分离整数,而无需转换为接口类型。