Function to retrieve CPUID does not compile in LAZARUS - lazarus

I'm trying to port some code from old Delphi7 to Lazarus but following code just won't compile. Lazarus always complains about unknown identifiers.
function GetCPUID(Leaf, Subleaf: Integer): TCPUID;
begin
asm
{$IF Defined(CPUX86)}
push ebx
push edi
mov edi, ecx
mov ecx, edx
cpuid
mov [edi+$0], eax
mov [edi+$4], ebx
mov [edi+$8], ecx
mov [edi+$c], edx
pop edi
pop ebx
{$ELSEIF Defined(CPUX64)}
mov r9,rcx
mov ecx,r8d
mov r8,rbx
mov eax,edx
cpuid
mov [r9+$0], eax
mov [r9+$4], ebx
mov [r9+$8], ecx
mov [r9+$c], edx
mov rbx, r8
{$ELSE}
{$Message Fatal 'GetCPUID has not been implemented for this architecture.'};
{$IFEND}
end;
ERROR MESSAGES
Compile Project, Target: C:\Users\Dave\AppData\Local\Temp\project1.exe: Exit code 1, Errors: 40, Warnings: 4
unit1.pas(65,9) Error: Unknown identifier "R9"
unit1.pas(65,12) Error: Unknown identifier "RCX"
unit1.pas(66,9) Error: Unknown identifier "ECX"
unit1.pas(66,13) Error: Unknown identifier "R8D"
unit1.pas(67,9) Error: Unknown identifier "R8"
unit1.pas(67,12) Error: Unknown identifier "RBX"
unit1.pas(68,9) Error: Unknown identifier "EAX"
unit1.pas(68,13) Error: Unknown identifier "EDX"
unit1.pas(70,9) Error: Assembler syntax error in operand
unit1.pas(70,10) Error: Unknown identifier "R9"
unit1.pas(70,14) Error: Dollar token is used without an identifier
unit1.pas(70,15) Error: Invalid constant expression
unit1.pas(70,16) Error: Invalid reference syntax
unit1.pas(70,18) Error: Unknown identifier "EAX"
unit1.pas(70,18) Error: No size specified and unable to determine the size of the operands
unit1.pas(70,18) Warning: Size suffix and destination or source size do not match
unit1.pas(71,9) Error: Assembler syntax error in operand
unit1.pas(71,10) Error: Unknown identifier "R9"
unit1.pas(71,14) Error: Dollar token is used without an identifier
unit1.pas(71,15) Error: Invalid constant expression
unit1.pas(71,16) Error: Invalid reference syntax
unit1.pas(71,18) Error: Unknown identifier "EBX"
unit1.pas(71,18) Error: No size specified and unable to determine the size of the operands
unit1.pas(71,18) Warning: Size suffix and destination or source size do not match
unit1.pas(72,9) Error: Assembler syntax error in operand
unit1.pas(72,10) Error: Unknown identifier "R9"
unit1.pas(72,14) Error: Dollar token is used without an identifier
unit1.pas(72,15) Error: Invalid constant expression
unit1.pas(72,16) Error: Invalid reference syntax
unit1.pas(72,18) Error: Unknown identifier "ECX"
unit1.pas(72,18) Error: No size specified and unable to determine the size of the operands
unit1.pas(72,18) Warning: Size suffix and destination or source size do not match
unit1.pas(73,9) Error: Assembler syntax error in operand
unit1.pas(73,10) Error: Unknown identifier "R9"
unit1.pas(73,15) Error: Unknown identifier "C"
unit1.pas(73,15) Error: Invalid constant expression
unit1.pas(73,16) Error: Invalid reference syntax
unit1.pas(73,18) Error: Unknown identifier "EDX"
unit1.pas(73,18) Error: No size specified and unable to determine the size of the operands
unit1.pas(73,18) Warning: Size suffix and destination or source size do not match
unit1.pas(74,9) Error: Unknown identifier "RBX"
unit1.pas(74,14) Error: Unknown identifier "R8"
unit1.pas(83,1) Error: Illegal expression
unit1.pas(83,11) Fatal: Syntax error, ";" expected but "identifier TFORM1" found

First, from the errors of the code that you show, it is clear this was not tested in Delphi 7, for the simple reason that Delphi 7 doesn't support 64-bit registers like R8 and R9
Moreover, for Delphi compatibility enable a Delphi compatibility mode, try adding
{$mode delphi}
if you want to use default Lazarus {$mode objfpc}, add
{$asmmode intel}
after the mode command
after the program or interface keywords. In addition your IFDEF clauses (CPUX86 and x64) don't seem to match FPC's.
Btw, many CPU tests have been prepared in unit cpu:
{ returns true, if the processor supports the cpuid instruction }
function cpuid_support : boolean;
{ returns true, if floating point is done by an emulator }
function floating_point_emulation : boolean;
{ returns the contents of the cr0 register }
function cr0 : longint;
function InterlockedCompareExchange128Support : boolean;
function AESSupport : boolean;inline;
function AVXSupport: boolean;inline;
function AVX2Support: boolean;inline;
function AVX512FSupport: boolean;inline;
function AVX512DQSupport: boolean;inline;
function AVX512IFMASupport: boolean;inline;
function AVX512PFSupport: boolean;inline;
function AVX512ERSupport: boolean;inline;
function AVX512CDSupport: boolean;inline;
function AVX512BWSupport: boolean;inline;
function AVX512VLSupport: boolean;inline;
function SHASupport: boolean;inline;
function FMASupport: boolean;inline;
function POPCNTSupport: boolean;inline;
function SSE41Support: boolean;inline;
function SSE42Support: boolean;inline;
function MOVBESupport: boolean;inline;
function F16CSupport: boolean;inline;
function RDRANDSupport: boolean;inline;
function RTMSupport: boolean;inline;
function BMI1Support: boolean;inline;
function BMI2Support: boolean;inline;
var
is_sse3_cpu : boolean = false;
I suggest to use these as much as possible.

Related

NASM x86_64, Redifining Labels

My Goal is to redifine an existing label in the .data section of my Nasm Code.
The expected result shoud be that the existing memory label gets overwritten by the same procedure
The occuring errormessages are:
exp3.asm:230: error: comma, colon, decorator or end of line expected after operand
exp3.asm:191: ... from macro `var' defined here
exp3.asm:230: warning: character constant too long
exp3.asm:191: ... from macro `var' defined here
exp3.asm:230: error: parser: instruction expected
exp3.asm:195: ... from macro `var' defined here
exp3.asm:231: error: comma, colon, decorator or end of line expected after operand
exp3.asm:191: ... from macro `var' defined here
exp3.asm:231: error: symbol `test' redefined
exp3.asm:195: ... from macro `var' defined here
exp3.asm:231: error: parser: instruction expected
exp3.asm:195: ... from macro `var' defined here
Ive tried to rearange the word types, but it just complicated the problem instead of solving it.
The Required Macros:
%macro ifexis 3
push rax ; make room
mov rax, %1 ; platziere wert in Vergleichsregister
test rax, rax ; wenn werte gleich oder nicht leer
jz [%2] ; Gehe zu erfolg
jmp [%3] ; gehe zu fail
pop rax ; clear rax
%endmacro
Checks if the value exists by loading the Contents in to RAX and then testing it against eachother
%macro var 2
ifexis %1, %%overwrite, %%establish ;<--------------------------------------- Für gleiche labels muss eine lösung gefunden werden
%%overwrite: ;<---------------------------------------------------------------
mov db[%1], %2 ;<-------------------------------------------------------------
jmp %%end;<-------------------------------------------------------------------
%%establish:;<----------------------------------------------------------------
section .data
%1: db %2
;db 0
section .text
%%end:
%endmacro
Test code:
section .text
global _start
_start:
var test, "a"
var test, "b"
Any aditional sources for learning Assembler are welcome

x86 Assembly program wont build

I have a program that was an example from our textbook, however when i put it in visual studio i get all kinds of errors. I am very new to Assembly, so I don't really know what this code is supposed to do, and i don't know why it is not working. Here is the code:
.model flat,c
.code
; extern "C" int CalcResult1_(int a, int b, int c);
CalcResult1_ proc
push ebp
mov ebp,esp
mov eax,[ebp+8]
mov ecx,[ebp+12]
mov edx,[ebp+16]
add eax,ecx
imul eax,edx
pop ebp
ret
CalcResult1_ endp
end
Here are the errors it gives:
1>------ Build started: Project: CompOrgHW2, Configuration: Debug Win32 ------
1>assembly_.asm
1>g:\comporghw2\comporghw2\assembly_.asm(1): error C2059: syntax error: '.'
1>g:\comporghw2\comporghw2\assembly_.asm(2): error C2059: syntax error: '.'
1>g:\comporghw2\comporghw2\assembly_.asm(7): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>g:\comporghw2\comporghw2\assembly_.asm(7): error C2365: 'CalcResult1_': redefinition; previous definition was 'function'
1>g:\comporghw2\comporghw2\assembly_.asm(4): note: see declaration of 'CalcResult1_'
1>g:\comporghw2\comporghw2\assembly_.asm(7): error C2146: syntax error: missing ';' before identifier 'proc'
1>Done building project "CompOrgHW2.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

powerpc-gcc inline assembly function

i want to use mtspr instruction for a special purpose register whose number in passed to me in a function.
__MTSPR(unsigned int spr, long long val)
i have to put val in spr.
here is what i tried in vain.
__asm__(
"mtspr %[a], %[b] "
: : [a]"I"(spr), [b]"r"(val)
);
i get this error :
ppc_gnu.c: In function '__MTSPR':
ppc_gnu.c:69:2: warning: asm operand 0 probably doesn't match constraints [enabled by default]
ppc_gnu.c:69:2: error: impossible constraint in 'asm'
so how to solve this problem and please no MACROs. i can not modify this function's usage or declaration.

GCC Inline assembler access arguments?

I need to access an argument from a C function
void printk(char* msg);
and store it into ESI. However I can not do
mov $msg, %esi
or
mov $_msg, %esi
Both return a linker error (Saying that the symbol msg or _msg is undefined. I am pretty sure I could access msg by reading from the stack but it would be easier just to access the symbol msg in my assembly code. Is this even possible in GCC?
You can't refer to variables like that in GCC inline assembly. I think you want something like:
asm("mov %[msg], %%esi",
: /* no outputs */
: [msg] "r" (msg)
: "esi");

install Ruby 1.8.6 with rvm in Mac OS X 10.6 Snow Leopard failed

I'm trying to learn Ruby on Rails and wanted to follow Apple's example:
http://developer.apple.com/tools/developonrailsleopard.html
It requires Ruby 1.8.6 and Rails 2.0.2
My machines is already updated to 1.9.1. I wanted to use rvm to install 1.8.6 but it failed during make with the following log:
[2010-10-20 10:43:31] make
eval.c: In function ‘rb_eval_string_wrap’:
eval.c:1743: warning: assignment discards qualifiers from pointer target type
eval.c: In function ‘rb_eval_cmd’:
eval.c:1884: warning: assignment discards qualifiers from pointer target type
eval.c: In function ‘call_trace_func’:
eval.c:2735: warning: assignment discards qualifiers from pointer target type
eval.c: In function ‘rb_raise_jump’:
eval.c:4760: warning: assignment discards qualifiers from pointer target type
eval.c: In function ‘method_missing’:
eval.c:5684: warning: assignment discards qualifiers from pointer target type
eval.c: In function ‘rb_call0’:
eval.c:5847: warning: assignment discards qualifiers from pointer target type
eval.c: In function ‘rb_f_eval’:
eval.c:6634: warning: assignment discards qualifiers from pointer target type
eval.c: In function ‘exec_under’:
eval.c:6658: warning: assignment discards qualifiers from pointer target type
eval.c: In function ‘rb_load’:
eval.c:6894: warning: assignment discards qualifiers from pointer target type
eval.c: In function ‘call_end_proc’:
eval.c:7924: warning: assignment discards qualifiers from pointer target type
eval.c: In function ‘rb_f_END’:
eval.c:7937: warning: assignment discards qualifiers from pointer target type
eval.c: In function ‘mproc’:
eval.c:9557: warning: assignment discards qualifiers from pointer target type
file.c: In function ‘lchmod_internal’:
file.c:1787: warning: cast from pointer to integer of different size
gc.c: In function ‘obj_free’:
gc.c:1287: warning: initialization from incompatible pointer type
regex.c: In function ‘ruby_re_compile_pattern’:
regex.c:1362: warning: format ‘%d’ expects type ‘int’, but argument 7 has type ‘long int’
regex.c:2026: warning: format ‘%d’ expects type ‘int’, but argument 6 has type ‘long int’
ptr.c: In function ‘rb_dlptr_inspect’:
ptr.c:461: warning: format ‘%lx’ expects type ‘long unsigned int’, but argument 7 has type ‘struct ptr_data *’
ptr.c:461: warning: format ‘%lx’ expects type ‘long unsigned int’, but argument 8 has type ‘void *’
void
char
short
int
long
float
double
sym.c: In function ‘rb_dlsym_inspect’:
sym.c:270: warning: format ‘%lx’ expects type ‘long unsigned int’, but argument 6 has type ‘struct sym_data *’
sym.c:270: warning: format ‘%lx’ expects type ‘long unsigned int’, but argument 7 has type ‘void *’
ossl_asn1.c: In function ‘decode_bool’:
ossl_asn1.c:313: warning: passing argument 2 of ‘d2i_ASN1_BOOLEAN’ from incompatible pointer type
ossl_asn1.c: In function ‘decode_int’:
ossl_asn1.c:328: warning: passing argument 2 of ‘d2i_ASN1_INTEGER’ from incompatible pointer type
ossl_asn1.c: In function ‘decode_bstr’:
ossl_asn1.c:347: warning: passing argument 2 of ‘d2i_ASN1_BIT_STRING’ from incompatible pointer type
ossl_asn1.c: In function ‘decode_enum’:
ossl_asn1.c:373: warning: passing argument 2 of ‘d2i_ASN1_ENUMERATED’ from incompatible pointer type
ossl_asn1.c: In function ‘decode_null’:
ossl_asn1.c:390: warning: passing argument 2 of ‘d2i_ASN1_NULL’ from incompatible pointer type
ossl_asn1.c: In function ‘decode_obj’:
ossl_asn1.c:407: warning: passing argument 2 of ‘d2i_ASN1_OBJECT’ from incompatible pointer type
ossl_asn1.c: In function ‘decode_time’:
ossl_asn1.c:435: warning: passing argument 2 of ‘d2i_ASN1_TIME’ from incompatible pointer type
ossl_asn1.c: In function ‘ossl_asn1_get_asn1type’:
ossl_asn1.c:503: warning: cast to pointer from integer of different size
ossl_asn1.c: In function ‘ossl_asn1_decode0’:
ossl_asn1.c:727: warning: passing argument 1 of ‘ASN1_get_object’ from incompatible pointer type
ossl_ns_spki.c: In function ‘ossl_spki_initialize’:
ossl_ns_spki.c:67: warning: passing argument 2 of ‘d2i_NETSCAPE_SPKI’ from incompatible pointer type
ossl_ocsp.c: In function ‘ossl_ocspreq_initialize’:
ossl_ocsp.c:114: warning: passing argument 2 of ‘d2i_OCSP_REQUEST’ from incompatible pointer type
ossl_ocsp.c: In function ‘ossl_ocspres_initialize’:
ossl_ocsp.c:321: warning: passing argument 2 of ‘d2i_OCSP_RESPONSE’ from incompatible pointer type
ossl_pkcs7.c: In function ‘ossl_pkcs7si_new’:
ossl_pkcs7.c:90: warning: passing argument 2 of ‘ASN1_dup’ from incompatible pointer type
ossl_pkcs7.c: In function ‘DupPKCS7SignerPtr’:
ossl_pkcs7.c:103: warning: passing argument 2 of ‘ASN1_dup’ from incompatible pointer type
ossl_pkcs7.c: In function ‘ossl_pkcs7ri_new’:
ossl_pkcs7.c:116: warning: passing argument 2 of ‘ASN1_dup’ from incompatible pointer type
ossl_pkcs7.c: In function ‘DupPKCS7RecipientPtr’:
ossl_pkcs7.c:129: warning: passing argument 2 of ‘ASN1_dup’ from incompatible pointer type
ossl_pkey_dsa.c: In function ‘ossl_dsa_initialize’:
ossl_pkey_dsa.c:141: warning: passing argument 1 of ‘PEM_ASN1_read_bio’ from incompatible pointer type
ossl_pkey_dsa.c:141: warning: passing argument 4 of ‘PEM_ASN1_read_bio’ from incompatible pointer type
ossl_pkey_dsa.c: In function ‘ossl_dsa_to_public_key’:
ossl_pkey_dsa.c:313: warning: passing argument 2 of ‘ASN1_dup’ from incompatible pointer type
ossl_x509attr.c: In function ‘ossl_x509attr_initialize’:
ossl_x509attr.c:100: warning: passing argument 2 of ‘d2i_X509_ATTRIBUTE’ from incompatible pointer type
ossl_x509ext.c: In function ‘ossl_x509ext_initialize’:
ossl_x509ext.c:285: warning: passing argument 2 of ‘d2i_X509_EXTENSION’ from incompatible pointer type
ossl_x509name.c: In function ‘ossl_x509name_initialize’:
ossl_x509name.c:135: warning: passing argument 2 of ‘d2i_X509_NAME’ from incompatible pointer type
ossl_x509revoked.c: In function ‘ossl_x509revoked_new’:
ossl_x509revoked.c:48: warning: passing argument 2 of ‘ASN1_dup’ from incompatible pointer type
ossl_x509revoked.c: In function ‘DupX509RevokedPtr’:
ossl_x509revoked.c:64: warning: passing argument 2 of ‘ASN1_dup’ from incompatible pointer type
readline.c: In function ‘username_completion_proc_call’:
readline.c:730: error: ‘username_completion_function’ undeclared (first use in this function)
readline.c:730: error: (Each undeclared identifier is reported only once
readline.c:730: error: for each function it appears in.)
make[1]: *** [readline.o] Error 1
make: *** [all] Error 1
[2010-10-20 10:50:17] make
readline.c: In function ‘username_completion_proc_call’:
readline.c:730: error: ‘username_completion_function’ undeclared (first use in this function)
readline.c:730: error: (Each undeclared identifier is reported only once
readline.c:730: error: for each function it appears in.)
make[1]: *** [readline.o] Error 1
make: *** [all] Error 1
[2010-10-20 11:48:12] make
readline.c: In function ‘username_completion_proc_call’:
readline.c:730: error: ‘username_completion_function’ undeclared (first use in this function)
readline.c:730: error: (Each undeclared identifier is reported only once
readline.c:730: error: for each function it appears in.)
make[1]: *** [readline.o] Error 1
make: *** [all] Error 1
[2010-10-20 15:30:53] make
readline.c: In function ‘username_completion_proc_call’:
readline.c:730: error: ‘username_completion_function’ undeclared (first use in this function)
readline.c:730: error: (Each undeclared identifier is reported only once
readline.c:730: error: for each function it appears in.)
make[1]: *** [readline.o] Error 1
make: *** [all] Error 1
[2010-10-20 17:19:27] make
readline.c: In function ‘username_completion_proc_call’:
readline.c:730: error: ‘username_completion_function’ undeclared (first use in this function)
readline.c:730: error: (Each undeclared identifier is reported only once
readline.c:730: error: for each function it appears in.)
make[1]: *** [readline.o] Error 1
make: *** [all] Error 1
Can anyone help? I'm totally lost here…
That article i 2.5 years old. I wouldn't recommend following it. If you still wants to then you could try to rvm install Ruby 1.8.7. I've never heard of any compability issues between 1.8.6 and 1.8.7.
I would instead recommend that you follow Setting up a Rails Development System on Mac OSX Snow Leopard and from there the regular Getting Started with Rails.

Resources