declare
type ff is array (0 .. 10) of Unsigned_32;
pragma Pack(ff);
Flags : aliased ff := (others => 0);
Flag_Address : System.Address := Flags'Address;
begin
Asm ( "movl %0, %%eax" &
"movl $1, (%%eax)" ,
Inputs => System.Address'Asm_Input ("g", Flag_Address),
Clobber => "eax",
Volatile => true
);
Put_Line ("Output:" & Flags(0)'Img);
end;
On 10/6/22 07:30, NiGHTS wrote:
declare
         type ff is array (0 .. 10) of Unsigned_32;
         pragma Pack(ff);
         Flags : aliased ff := (others => 0);
         Flag_Address : System.Address := Flags'Address;
begin
        Asm (  "movl %0, %%eax" &
                "movl $1, (%%eax)" ,
                Inputs  => System.Address'Asm_Input ("g",
Flag_Address),
                Clobber => "eax",
                Volatile => true
        );
        Put_Line ("Output:" & Flags(0)'Img);
end;
  If you are on a 64 bit machine, then I expect 'pragma Pack' might
be the problem, as 2 consecutive array elements will fir into a single address.
  Also, possibly use ...
  Flag_Address : System.Address := Flags (Flags'First)'Address;
Regards.There maybe a a way around this problem, if there is a compiler that can
On 10/6/22 07:30, NiGHTS wrote:
declare
         type ff is array (0 .. 10) of Unsigned_32;
         pragma Pack(ff);
         Flags : aliased ff := (others => 0);
         Flag_Address : System.Address := Flags'Address;
begin
        Asm (  "movl %0, %%eax" &
                "movl $1, (%%eax)" ,
                Inputs  => System.Address'Asm_Input ("g",
Flag_Address),
                Clobber => "eax",
                Volatile => true
        );
        Put_Line ("Output:" & Flags(0)'Img);
end;
  If you are on a 64 bit machine, then I expect 'pragma Pack' might be the problem, as 2 consecutive array elements will fir into a single
address.
  Also, possibly use ...
  Flag_Address : System.Address := Flags (Flags'First)'Address;
Regards.
On 10/06/2022 06:24, Rod Kay wrote:
On 10/6/22 07:30, NiGHTS wrote:
declare
type ff is array (0 .. 10) of Unsigned_32;
pragma Pack(ff);
Flags : aliased ff := (others => 0);
Flag_Address : System.Address := Flags'Address;
begin
Asm ( "movl %0, %%eax" &
"movl $1, (%%eax)" ,
Inputs => System.Address'Asm_Input ("g",
Flag_Address),
Clobber => "eax",
Volatile => true
);
Put_Line ("Output:" & Flags(0)'Img);
end;
If you are on a 64 bit machine, then I expect 'pragma Pack' might be the problem, as 2 consecutive array elements will fir into a single address.
Also, possibly use ...
Flag_Address : System.Address := Flags (Flags'First)'Address;
Regards.Dump the xpanded (generated code) and the assembly from gnat.
Op 10-6-2022 om 7:24 schreef Rod Kay:
On 10/6/22 07:30, NiGHTS wrote:
declare
type ff is array (0 .. 10) of Unsigned_32;
pragma Pack(ff);
Flags : aliased ff := (others => 0);
Flag_Address : System.Address := Flags'Address;
begin
Asm ( "movl %0, %%eax" &
"movl $1, (%%eax)" ,
Inputs => System.Address'Asm_Input ("g", Flag_Address),
Clobber => "eax",
Volatile => true
);
Put_Line ("Output:" & Flags(0)'Img);
end;
If you are on a 64 bit machine, then I expect 'pragma Pack' might be the problem, as 2 consecutive array elements will fir into a single address.
Also, possibly use ...
Flag_Address : System.Address := Flags (Flags'First)'Address;
Regards.that part of your work
There maybe a a way around this problem, if there is a compiler that can create assembly code. I have used that method in the past with Pascal programs where I wanted to avoid internal checks on errors that could not occur in that part of the program.
Warning: Programming the way you want to means that your program will mean that your program can become depending on the system you are working on. Meaning for instance not only recompiling when migrating from Windows to Linux but also reprogramming
On 10/6/22 07:30, NiGHTS wrote:
declare
type ff is array (0 .. 10) of Unsigned_32;
pragma Pack(ff);
Flags : aliased ff := (others => 0);
Flag_Address : System.Address := Flags'Address;
begin
Asm ( "movl %0, %%eax" &
"movl $1, (%%eax)" ,
Inputs => System.Address'Asm_Input ("g", Flag_Address),
Clobber => "eax",
Volatile => true
);
Put_Line ("Output:" & Flags(0)'Img);
end;
If you are on a 64 bit machine, then I expect 'pragma Pack' might be
the problem, as 2 consecutive array elements will fir into a single address.
Also, possibly use ...
Flag_Address : System.Address := Flags (Flags'First)'Address;
Regards.
I also am not entirely sure why there would be a difference between the address of the first element versus the address of the array itself (maybe that's just my C instincts kicking in).
declare
type ff is array (0 .. 10) of Unsigned_32;
pragma Pack(ff);
Flags : aliased ff := (others => 0);
Flag_Address : System.Address := Flags'Address;
begin
Asm ( "movl %0, %%eax" &
"movl $1, (%%eax)" ,
Inputs => System.Address'Asm_Input ("g", Flag_Address),
Clobber => "eax",
Volatile => true
);
Put_Line ("Output:" & Flags(0)'Img);
end;
On 2022-06-09 23:30, NiGHTS wrote:On my side I had the LF HT characters. I copied the code badly to this posting. So though you are right, my post lied a little bit by accident. This didn't end up being the main problem.
declareHave you looked at the GNAT User's Guide section on this (https://docs.adacore.com/live/wave/gnat_ugn/html/gnat_ugn/gnat_ugn/inline_assembler.html)?
type ff is array (0 .. 10) of Unsigned_32;
pragma Pack(ff);
Flags : aliased ff := (others => 0);
Flag_Address : System.Address := Flags'Address;
begin
Asm ( "movl %0, %%eax" &
"movl $1, (%%eax)" ,
Inputs => System.Address'Asm_Input ("g", Flag_Address),
Clobber => "eax",
Volatile => true
);
Put_Line ("Output:" & Flags(0)'Img);
end;
I have never used this, but the first thing I notice is that the examples in the
User's Guide put an LF-HT pair between statements:
Asm ("pushfl" & LF & HT & -- push flags on stack
"popl %%eax" & LF & HT & -- load eax with flags
"movl %%eax, %0", -- store flags in variable
Outputs => Unsigned_32'Asm_Output ("=g", Flags));
It is also legal to separate the statements with spaces, but what you have would
seem to be
movl %0, %%eaxmovl $1, (%%eax)
which may be a problem.
--
Jeff Carter
"I'm a lumberjack and I'm OK."
Monty Python's Flying Circus
54
On 10/6/22 07:30, NiGHTS wrote:
  If you are on a 64 bit machine, then I expect 'pragma Pack' might be the problem, as 2 consecutive array elements will fir into a single
address.
NiGHTS <nig...@unku.us> writes:I haven't tested this yet but the solution makes sense to me. Thank you for your help!
This was my first experiment which produces a memory access error. In
this early version I'm just trying to write to the first element.
declareI got an access error as well (macOS, GCC 12.1.0, 64 bits).
type ff is array (0 .. 10) of Unsigned_32;
pragma Pack(ff);
Flags : aliased ff := (others => 0);
Flag_Address : System.Address := Flags'Address;
begin
Asm ( "movl %0, %%eax" &
"movl $1, (%%eax)" ,
Inputs => System.Address'Asm_Input ("g", Flag_Address),
Clobber => "eax",
Volatile => true
);
Put_Line ("Output:" & Flags(0)'Img);
end;
Eventually, it turned out that the problem was that eax is a 32-bit
register. (the compiler used rdx, and the assembler told me that
movl %rdx, %eax wasn't allowed).
This is my working code; Flags is volatile, because otherwise the
compiler doesn't realise (at -O2) that Flags (0) has been touched.
ALso, note the Inputs line!
====
with System.Machine_Code; use System.Machine_Code;
with Interfaces; use Interfaces;
with Ada.Text_IO; use Ada.Text_IO;
procedure Nights is
type Ff is array (0 .. 10) of Unsigned_32;
Flags : aliased Ff := (others => 0) with Volatile;
begin
Asm (
"movq %0, %%rax" & ASCII.LF & ASCII.HT
& "movl $1, (%%rax)",
Inputs => System.Address'Asm_Input ("g", Flags (Flags'First)'Address), Clobber => "rax",
Volatile => True
);
Put_Line ("Output:" & Flags(0)'Img);
end Nights;
This was my first experiment which produces a memory access error. In
this early version I'm just trying to write to the first element.
declare
type ff is array (0 .. 10) of Unsigned_32;
pragma Pack(ff);
Flags : aliased ff := (others => 0);
Flag_Address : System.Address := Flags'Address;
begin
Asm ( "movl %0, %%eax" &
"movl $1, (%%eax)" ,
Inputs => System.Address'Asm_Input ("g", Flag_Address),
Clobber => "eax",
Volatile => true
);
Put_Line ("Output:" & Flags(0)'Img);
end;
I would like to write an inline assembly code in Ada that simply writes a constant to a specific element of an array of unsigned values.
I'm shooting in the dark here because there are absolutely no references on this subject, to my surprise.
This was my first experiment which produces a memory access error. In this early version I'm just trying to write to the first element.
declare
type ff is array (0 .. 10) of Unsigned_32;
pragma Pack(ff);
Flags : aliased ff := (others => 0);
Flag_Address : System.Address := Flags'Address;
begin
Asm ( "movl %0, %%eax" &
"movl $1, (%%eax)" ,
Inputs => System.Address'Asm_Input ("g", Flag_Address),
Clobber => "eax",
Volatile => true
);
Put_Line ("Output:" & Flags(0)'Img);
end;
Any help would be greatly appreciated!
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 399 |
Nodes: | 16 (3 / 13) |
Uptime: | 64:54:52 |
Calls: | 8,355 |
Calls today: | 15 |
Files: | 13,159 |
Messages: | 5,893,946 |
Posted today: | 1 |