* Help with Inline assembly
@ 2012-07-09 3:53 Jim C.
2012-07-09 6:35 ` anon
2012-07-09 8:41 ` theanalogmachine
0 siblings, 2 replies; 6+ messages in thread
From: Jim C. @ 2012-07-09 3:53 UTC (permalink / raw)
I am running into problems translating Intel style visual C inline assembly to something gnat can understand (http://gcc.gnu.org/onlinedocs/gnat_ugn_unw/Inline-Assembler.html#Inline-Assembler). The goal of the program is to test for the existence of the CPUID command which only exists after the 386.
The program as it stands compiles without any errors, but it will fail at runtime with the following printed: "raised PROGRAM_ERROR : EXCEPTION_ACCESS_VIOLATION" -- I can't tell if I am violating syntax or something more complicated is involved.
///////////////////////////////////// Visual C code
static bool HasCPUID( void ) {
__asm
{
pushfd // save eflags
pop eax
test eax, 0x00200000 // check ID bit
jz set21 // bit 21 is not set, so jump to set_21
and eax, 0xffdfffff // clear bit 21
push eax // save new value in register
popfd // store new value in flags
pushfd
pop eax
test eax, 0x00200000 // check ID bit
jz good
jmp err // cpuid not supported
set21:
or eax, 0x00200000 // set ID bit
push eax // store new value
popfd // store new value in EFLAGS
pushfd
pop eax
test eax, 0x00200000 // if bit 21 is on
jnz good
jmp err
}
err:
return false;
good:
return true;
}
--------------------------------------- Ada code
with
Ada.Text_IO,
Interfaces,
System.Machine_Code;
use
Ada.Text_IO,
Interfaces,
System.Machine_Code;
procedure Assembly_Test
is
C : Character := Ascii.Nul;
Result : Unsigned_32 := 0;
begin
Asm(
-------------------------------------------------------
" pushf " & Ascii.LF & Ascii.HT &
" pop %%eax " & Ascii.LF & Ascii.HT &
" test %%eax, 0x00200000 " & Ascii.LF & Ascii.HT &
" jz set21 " & Ascii.LF & Ascii.HT &
" and %%eax, 0xffdfffff " & Ascii.LF & Ascii.HT &
" push %%eax " & Ascii.LF & Ascii.HT &
" popf " & Ascii.LF & Ascii.HT &
" pushf " & Ascii.LF & Ascii.HT &
" pop %%eax " & Ascii.LF & Ascii.HT &
" test %%eax, 0x00200000 " & Ascii.LF & Ascii.HT &
" jz good " & Ascii.LF & Ascii.HT &
" jmp err " & Ascii.LF & Ascii.HT &
-------------------------------------------------------
" set21: " & Ascii.LF & Ascii.HT &
" or %%eax, 0x00200000 " & Ascii.LF & Ascii.HT &
" push %%eax " & Ascii.LF & Ascii.HT &
" popf " & Ascii.LF & Ascii.HT &
" pushf " & Ascii.LF & Ascii.HT &
" pop %%eax " & Ascii.LF & Ascii.HT &
" test %%eax, 0x00200000 " & Ascii.LF & Ascii.HT &
" jnz good " & Ascii.LF & Ascii.HT &
" jmp err " & Ascii.LF & Ascii.HT &
-------------------------------------------------------
" err: " & Ascii.LF & Ascii.HT &
" mov 0x0, %%eax " & Ascii.LF & Ascii.HT &
-------------------------------------------------------
" good: " & Ascii.LF & Ascii.HT &
" mov 0x1, %%eax " & Ascii.LF & Ascii.HT ,
-------------------------------------------------------
Outputs => Unsigned_32'Asm_Output("=a", Result),
Volatile => True);
if Result /= 1 then
Put_Line("False");
end if;
Put_Line("True");
Get(C);
end Assembly_Test;
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Help with Inline assembly
2012-07-09 3:53 Help with Inline assembly Jim C.
@ 2012-07-09 6:35 ` anon
2012-07-09 8:41 ` theanalogmachine
1 sibling, 0 replies; 6+ messages in thread
From: anon @ 2012-07-09 6:35 UTC (permalink / raw)
alter code to look like this:
-------------------------------------------------------
" err: " & Ascii.LF & Ascii.HT &
" mov 0x0, %%eax " & Ascii.LF & Ascii.HT &
" jmp ret " & Ascii.LF & Ascii.HT & -- added
-------------------------------------------------------
" good: " & Ascii.LF & Ascii.HT &
" mov 0x1, %%eax " & Ascii.LF & Ascii.HT &
-------------------------------------------------------
" ret:" ", -- added
remove the "-- added" comment
In <85b57cc7-352e-4cee-a161-b0aaf1665305@googlegroups.com>, "Jim C." <theanalogmachine@gmail.com> writes:
>I am running into problems translating Intel style visual C inline assembly=
> to something gnat can understand (http://gcc.gnu.org/onlinedocs/gnat_ugn_u=
>nw/Inline-Assembler.html#Inline-Assembler). The goal of the program is to t=
>est for the existence of the CPUID command which only exists after the 386.
>
>The program as it stands compiles without any errors, but it will fail at r=
>untime with the following printed: "raised PROGRAM_ERROR : EXCEPTION_ACCESS=
>_VIOLATION" -- I can't tell if I am violating syntax or something more comp=
>licated is involved.
>
>///////////////////////////////////// Visual C code
>static bool HasCPUID( void ) {
> __asm=20
> {
> pushfd // save eflags
> pop eax
> test eax, 0x00200000 // check ID bit
> jz set21 // bit 21 is not set, so jump to set_21
> and eax, 0xffdfffff // clear bit 21
> push eax // save new value in register
> popfd // store new value in flags
> pushfd
> pop eax
> test eax, 0x00200000 // check ID bit
> jz good
> jmp err // cpuid not supported
> set21:
> or eax, 0x00200000 // set ID bit
> push eax // store new value
> popfd // store new value in EFLAGS
> pushfd
> pop eax
> test eax, 0x00200000 // if bit 21 is on
> jnz good
> jmp err
> }
> err:
> return false;
> good:
> return true;
>}
>
>--------------------------------------- Ada code
>with
> Ada.Text_IO,
> Interfaces,
> System.Machine_Code;
>use
> Ada.Text_IO,
> Interfaces,
> System.Machine_Code;
>procedure Assembly_Test
> is
> C : Character :=3D Ascii.Nul;
> Result : Unsigned_32 :=3D 0;
> begin
> Asm(
> -------------------------------------------------------
> " pushf " & Ascii.LF & Ascii.HT &
> " pop %%eax " & Ascii.LF & Ascii.HT &=20
> " test %%eax, 0x00200000 " & Ascii.LF & Ascii.HT &
> " jz set21 " & Ascii.LF & Ascii.HT &
> " and %%eax, 0xffdfffff " & Ascii.LF & Ascii.HT &
> " push %%eax " & Ascii.LF & Ascii.HT &
> " popf " & Ascii.LF & Ascii.HT &
> " pushf " & Ascii.LF & Ascii.HT &=20
> " pop %%eax " & Ascii.LF & Ascii.HT &=20
> " test %%eax, 0x00200000 " & Ascii.LF & Ascii.HT &
> " jz good " & Ascii.LF & Ascii.HT &=20
> " jmp err " & Ascii.LF & Ascii.HT &
> -------------------------------------------------------
> " set21: " & Ascii.LF & Ascii.HT &=20
> " or %%eax, 0x00200000 " & Ascii.LF & Ascii.HT &
> " push %%eax " & Ascii.LF & Ascii.HT &
> " popf " & Ascii.LF & Ascii.HT &
> " pushf " & Ascii.LF & Ascii.HT &=20
> " pop %%eax " & Ascii.LF & Ascii.HT &=20
> " test %%eax, 0x00200000 " & Ascii.LF & Ascii.HT &
> " jnz good " & Ascii.LF & Ascii.HT &=20
> " jmp err " & Ascii.LF & Ascii.HT & =20
> -------------------------------------------------------
> " err: " & Ascii.LF & Ascii.HT &=20
> " mov 0x0, %%eax " & Ascii.LF & Ascii.HT &=20
> -------------------------------------------------------
> " good: " & Ascii.LF & Ascii.HT &=20
> " mov 0x1, %%eax " & Ascii.LF & Ascii.HT ,=20
> -------------------------------------------------------
> Outputs =3D> Unsigned_32'Asm_Output("=3Da", Result),
> Volatile =3D> True);
> if Result /=3D 1 then
> Put_Line("False");
> end if;
> Put_Line("True");
> Get(C);
> end Assembly_Test;
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Help with Inline assembly
2012-07-09 3:53 Help with Inline assembly Jim C.
2012-07-09 6:35 ` anon
@ 2012-07-09 8:41 ` theanalogmachine
2012-07-09 14:43 ` theanalogmachine
1 sibling, 1 reply; 6+ messages in thread
From: theanalogmachine @ 2012-07-09 8:41 UTC (permalink / raw)
Thanks for the reply, it seems your suggestion did not fix my primary problem (that a EXCEPTION_ACCESS_VIOLATION is displayed at runtime). Could you elaborate more on your suggestion?
On Sunday, July 8, 2012 11:53:05 PM UTC-4, Jim C. wrote:
> I am running into problems translating Intel style visual C inline assembly to something gnat can understand (http://gcc.gnu.org/onlinedocs/gnat_ugn_unw/Inline-Assembler.html#Inline-Assembler). The goal of the program is to test for the existence of the CPUID command which only exists after the 386.
>
> The program as it stands compiles without any errors, but it will fail at runtime with the following printed: "raised PROGRAM_ERROR : EXCEPTION_ACCESS_VIOLATION" -- I can't tell if I am violating syntax or something more complicated is involved.
>
> ///////////////////////////////////// Visual C code
> static bool HasCPUID( void ) {
> __asm
> {
> pushfd // save eflags
> pop eax
> test eax, 0x00200000 // check ID bit
> jz set21 // bit 21 is not set, so jump to set_21
> and eax, 0xffdfffff // clear bit 21
> push eax // save new value in register
> popfd // store new value in flags
> pushfd
> pop eax
> test eax, 0x00200000 // check ID bit
> jz good
> jmp err // cpuid not supported
> set21:
> or eax, 0x00200000 // set ID bit
> push eax // store new value
> popfd // store new value in EFLAGS
> pushfd
> pop eax
> test eax, 0x00200000 // if bit 21 is on
> jnz good
> jmp err
> }
> err:
> return false;
> good:
> return true;
> }
>
> --------------------------------------- Ada code
> with
> Ada.Text_IO,
> Interfaces,
> System.Machine_Code;
> use
> Ada.Text_IO,
> Interfaces,
> System.Machine_Code;
> procedure Assembly_Test
> is
> C : Character := Ascii.Nul;
> Result : Unsigned_32 := 0;
> begin
> Asm(
> -------------------------------------------------------
> " pushf " & Ascii.LF & Ascii.HT &
> " pop %%eax " & Ascii.LF & Ascii.HT &
> " test %%eax, 0x00200000 " & Ascii.LF & Ascii.HT &
> " jz set21 " & Ascii.LF & Ascii.HT &
> " and %%eax, 0xffdfffff " & Ascii.LF & Ascii.HT &
> " push %%eax " & Ascii.LF & Ascii.HT &
> " popf " & Ascii.LF & Ascii.HT &
> " pushf " & Ascii.LF & Ascii.HT &
> " pop %%eax " & Ascii.LF & Ascii.HT &
> " test %%eax, 0x00200000 " & Ascii.LF & Ascii.HT &
> " jz good " & Ascii.LF & Ascii.HT &
> " jmp err " & Ascii.LF & Ascii.HT &
> -------------------------------------------------------
> " set21: " & Ascii.LF & Ascii.HT &
> " or %%eax, 0x00200000 " & Ascii.LF & Ascii.HT &
> " push %%eax " & Ascii.LF & Ascii.HT &
> " popf " & Ascii.LF & Ascii.HT &
> " pushf " & Ascii.LF & Ascii.HT &
> " pop %%eax " & Ascii.LF & Ascii.HT &
> " test %%eax, 0x00200000 " & Ascii.LF & Ascii.HT &
> " jnz good " & Ascii.LF & Ascii.HT &
> " jmp err " & Ascii.LF & Ascii.HT &
> -------------------------------------------------------
> " err: " & Ascii.LF & Ascii.HT &
> " mov 0x0, %%eax " & Ascii.LF & Ascii.HT &
> -------------------------------------------------------
> " good: " & Ascii.LF & Ascii.HT &
> " mov 0x1, %%eax " & Ascii.LF & Ascii.HT ,
> -------------------------------------------------------
> Outputs => Unsigned_32'Asm_Output("=a", Result),
> Volatile => True);
> if Result /= 1 then
> Put_Line("False");
> end if;
> Put_Line("True");
> Get(C);
> end Assembly_Test;
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Help with Inline assembly
2012-07-09 8:41 ` theanalogmachine
@ 2012-07-09 14:43 ` theanalogmachine
2012-07-09 15:05 ` Jeffrey Carter
0 siblings, 1 reply; 6+ messages in thread
From: theanalogmachine @ 2012-07-09 14:43 UTC (permalink / raw)
I now have the program executing, and potentially functioning -- I won't know for sure until I test it with some sort of emulator that simulates older processors. Here is the fixed code for anyone interested (this came in handy too http://x86asm.net/articles/what-i-dislike-about-gas/)
-----------------------
-- Can_Execute_CPUID --
-----------------------
function Can_Execute_CPUID
return Boolean
is
Result : Unsigned_32 := 0;
begin
Asm(
--------------------------------------------------------
" begin: " & Ascii.LF & Ascii.HT &
" pushfl " & Ascii.LF & Ascii.HT &
" popl %%eax " & Ascii.LF & Ascii.HT &
" test $0x00200000, %%eax " & Ascii.LF & Ascii.HT &
" jz set21 " & Ascii.LF & Ascii.HT &
" and $0xffdfffff, %%eax " & Ascii.LF & Ascii.HT &
" pushl %%eax " & Ascii.LF & Ascii.HT &
" popfl " & Ascii.LF & Ascii.HT &
" pushfl " & Ascii.LF & Ascii.HT &
" popl %%eax " & Ascii.LF & Ascii.HT &
" test $0x00200000, %%eax " & Ascii.LF & Ascii.HT &
" jz good " & Ascii.LF & Ascii.HT &
" jmp error " & Ascii.LF & Ascii.HT &
--------------------------------------------------------
" set21: " & Ascii.LF & Ascii.HT &
" or $0x00200000, %%eax " & Ascii.LF & Ascii.HT &
" pushl %%eax " & Ascii.LF & Ascii.HT &
" popfl " & Ascii.LF & Ascii.HT &
" pushfl " & Ascii.LF & Ascii.HT &
" popl %%eax " & Ascii.LF & Ascii.HT &
" test $0x00200000, %%eax " & Ascii.LF & Ascii.HT &
" jnz good " & Ascii.LF & Ascii.HT &
" jmp error " & Ascii.LF & Ascii.HT &
--------------------------------------------------------
" error: " & Ascii.LF & Ascii.HT &
" movl $0x0, %%eax " & Ascii.LF & Ascii.HT &
" jmp end " & Ascii.LF & Ascii.HT &
--------------------------------------------------------
" good: " & Ascii.LF & Ascii.HT &
" movl $0x1, %%eax " & Ascii.LF & Ascii.HT &
--------------------------------------------------------
" end: " & Ascii.LF & Ascii.HT ,
--------------------------------------------------------
Outputs => Unsigned_32'Asm_Output("=a", Result),
Volatile => True);
if Result /= 1 then
return True;
end if;
return False;
end Can_Execute_CPUID;
On Monday, July 9, 2012 4:41:23 AM UTC-4, (unknown) wrote:
> Thanks for the reply, it seems your suggestion did not fix my primary problem (that a EXCEPTION_ACCESS_VIOLATION is displayed at runtime). Could you elaborate more on your suggestion?
>
> On Sunday, July 8, 2012 11:53:05 PM UTC-4, Jim C. wrote:
> > I am running into problems translating Intel style visual C inline assembly to something gnat can understand (http://gcc.gnu.org/onlinedocs/gnat_ugn_unw/Inline-Assembler.html#Inline-Assembler). The goal of the program is to test for the existence of the CPUID command which only exists after the 386.
> >
> > The program as it stands compiles without any errors, but it will fail at runtime with the following printed: "raised PROGRAM_ERROR : EXCEPTION_ACCESS_VIOLATION" -- I can't tell if I am violating syntax or something more complicated is involved.
> >
> > ///////////////////////////////////// Visual C code
> > static bool HasCPUID( void ) {
> > __asm
> > {
> > pushfd // save eflags
> > pop eax
> > test eax, 0x00200000 // check ID bit
> > jz set21 // bit 21 is not set, so jump to set_21
> > and eax, 0xffdfffff // clear bit 21
> > push eax // save new value in register
> > popfd // store new value in flags
> > pushfd
> > pop eax
> > test eax, 0x00200000 // check ID bit
> > jz good
> > jmp err // cpuid not supported
> > set21:
> > or eax, 0x00200000 // set ID bit
> > push eax // store new value
> > popfd // store new value in EFLAGS
> > pushfd
> > pop eax
> > test eax, 0x00200000 // if bit 21 is on
> > jnz good
> > jmp err
> > }
> > err:
> > return false;
> > good:
> > return true;
> > }
> >
> > --------------------------------------- Ada code
> > with
> > Ada.Text_IO,
> > Interfaces,
> > System.Machine_Code;
> > use
> > Ada.Text_IO,
> > Interfaces,
> > System.Machine_Code;
> > procedure Assembly_Test
> > is
> > C : Character := Ascii.Nul;
> > Result : Unsigned_32 := 0;
> > begin
> > Asm(
> > -------------------------------------------------------
> > " pushf " & Ascii.LF & Ascii.HT &
> > " pop %%eax " & Ascii.LF & Ascii.HT &
> > " test %%eax, 0x00200000 " & Ascii.LF & Ascii.HT &
> > " jz set21 " & Ascii.LF & Ascii.HT &
> > " and %%eax, 0xffdfffff " & Ascii.LF & Ascii.HT &
> > " push %%eax " & Ascii.LF & Ascii.HT &
> > " popf " & Ascii.LF & Ascii.HT &
> > " pushf " & Ascii.LF & Ascii.HT &
> > " pop %%eax " & Ascii.LF & Ascii.HT &
> > " test %%eax, 0x00200000 " & Ascii.LF & Ascii.HT &
> > " jz good " & Ascii.LF & Ascii.HT &
> > " jmp err " & Ascii.LF & Ascii.HT &
> > -------------------------------------------------------
> > " set21: " & Ascii.LF & Ascii.HT &
> > " or %%eax, 0x00200000 " & Ascii.LF & Ascii.HT &
> > " push %%eax " & Ascii.LF & Ascii.HT &
> > " popf " & Ascii.LF & Ascii.HT &
> > " pushf " & Ascii.LF & Ascii.HT &
> > " pop %%eax " & Ascii.LF & Ascii.HT &
> > " test %%eax, 0x00200000 " & Ascii.LF & Ascii.HT &
> > " jnz good " & Ascii.LF & Ascii.HT &
> > " jmp err " & Ascii.LF & Ascii.HT &
> > -------------------------------------------------------
> > " err: " & Ascii.LF & Ascii.HT &
> > " mov 0x0, %%eax " & Ascii.LF & Ascii.HT &
> > -------------------------------------------------------
> > " good: " & Ascii.LF & Ascii.HT &
> > " mov 0x1, %%eax " & Ascii.LF & Ascii.HT ,
> > -------------------------------------------------------
> > Outputs => Unsigned_32'Asm_Output("=a", Result),
> > Volatile => True);
> > if Result /= 1 then
> > Put_Line("False");
> > end if;
> > Put_Line("True");
> > Get(C);
> > end Assembly_Test;
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Help with Inline assembly
2012-07-09 14:43 ` theanalogmachine
@ 2012-07-09 15:05 ` Jeffrey Carter
2012-07-09 16:35 ` Jim C.
0 siblings, 1 reply; 6+ messages in thread
From: Jeffrey Carter @ 2012-07-09 15:05 UTC (permalink / raw)
On 07/09/2012 07:43 AM, theanalogmachine@gmail.com wrote:
> if Result /= 1 then
> return True;
> end if;
> return False;
Or simply
return Result /= 1;
--
Jeff Carter
"I didn't squawk about the steak, dear. I
merely said I didn't see that old horse
that used to be tethered outside here."
Never Give a Sucker an Even Break
103
--- Posted via news://freenews.netfront.net/ - Complaints to news@netfront.net ---
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Help with Inline assembly
2012-07-09 15:05 ` Jeffrey Carter
@ 2012-07-09 16:35 ` Jim C.
0 siblings, 0 replies; 6+ messages in thread
From: Jim C. @ 2012-07-09 16:35 UTC (permalink / raw)
Haha thanks, I can't believe I let that slip past
On Monday, July 9, 2012 11:05:12 AM UTC-4, Jeffrey Carter wrote:
> On 07/09/2012 07:43 AM, theanalogmachine@gmail.com wrote:
> > if Result /= 1 then
> > return True;
> > end if;
> > return False;
>
> Or simply
>
> return Result /= 1;
>
> --
> Jeff Carter
> "I didn't squawk about the steak, dear. I
> merely said I didn't see that old horse
> that used to be tethered outside here."
> Never Give a Sucker an Even Break
> 103
>
>
>
> --- Posted via news://freenews.netfront.net/ - Complaints to news@netfront.net ---
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2012-07-09 16:35 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-09 3:53 Help with Inline assembly Jim C.
2012-07-09 6:35 ` anon
2012-07-09 8:41 ` theanalogmachine
2012-07-09 14:43 ` theanalogmachine
2012-07-09 15:05 ` Jeffrey Carter
2012-07-09 16:35 ` Jim C.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox