Rot*_*er2 1 casting bit-manipulation 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;
Run Code Online (Sandbox Code Playgroud)
在把一些C代码翻译成Ada的时候,遇到了几个问题,网上也找不到很多资源。C 代码段是:
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;
Run Code Online (Sandbox Code Playgroud)
这是我试图将其翻译成的 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;
Run Code Online (Sandbox Code Playgroud)
我如何能够显示我在代码中突出显示的问题?在这种情况下,初学者可以使用任何资源来寻求帮助吗?提前致谢!
使用包 System.Storage_Elements 中的 To_Integer 函数将地址转换为整数,然后将该整数转换为 Interfaces.Unsigned_32 或 Unsigned_64(以合适的为准),以便您可以使用移位操作来提取位域。
除了移位和掩码操作之外,您当然可以使用除法和“mod”将整数分开,而无需转换为接口类型。