Page 1 of 1

help converting inline assembly to C-backend

Posted: Fri Mar 11, 2022 11:00 am
by morosh
Hello:
I used this snippet to get the CPU serial number:

Code: Select all

Procedure.s GetCPUSerialNumber2()
  ;GetCPUSerialNumber()
  Define highbits.l
  Define lowbits.l
  Define serial.q
  
  !MOV eax, $80000003
  !CPUID
  !MOV dword [p.v_lowbits], ecx
  !MOV dword [p.v_highbits], edx
  
  serial = lowbits | highbits << 32
  ProcedureReturn Hex(serial,#PB_Quad)
EndProcedure

Debug GetCPUSerialNumber2()
Now I like to use it with C-back end, I tried:

Code: Select all

Procedure.s GetCPUSerialNumber2()
  ;GetCPUSerialNumber()
  Define highbits.l
  Define lowbits.l
  Define serial.q
  
  ! asm("MOV eax, $80000003");
  ! asm("CPUID");
  ! asm("MOV dword [p.v_lowbits], ecx");
  ! asm("MOV dword [p.v_highbits], edx");
  
  serial = lowbits | highbits << 32
  ProcedureReturn Hex(serial,#PB_Quad)
EndProcedure

Debug GetCPUSerialNumber2()
I got errors, I have a very limited knowledge in assembly, how to change the above code to get it working?

Thanks

Re: help converting inline assembly to C-backend

Posted: Fri Mar 11, 2022 10:27 pm
by breeze4me
Try this.

Code: Select all

Procedure.s GetCPUSerialNumber2()
  ;GetCPUSerialNumber()
  Define highbits.l
  Define lowbits.l
  Define serial.q
  
  !__asm__ __volatile__ (".intel_syntax noprefix;"
  
  !"MOV eax, 0x80000003;"
  !"CPUID;"
  !"MOV %0, ecx;"
  !"MOV %1, edx;"
  
  !".att_syntax"
  !:"=r" (v_lowbits), "=r" (v_highbits)
  !:
  !: "eax", "ecx", "edx"
  !);
  
  serial = lowbits | highbits << 32
  ProcedureReturn Hex(serial,#PB_Quad)
EndProcedure

Debug GetCPUSerialNumber2()

Re: help converting inline assembly to C-backend

Posted: Sat Mar 12, 2022 11:09 am
by morosh
Thank you very much

Re: help converting inline assembly to C-backend

Posted: Wed Jan 25, 2023 4:47 am
by juergenkulow
The program outputs a part of the Processor Brand String.
https://en.wikipedia.org/wiki/CPUID
https://www.etallen.com/cpuid.html

Re: help converting inline assembly to C-backend

Posted: Wed Jan 25, 2023 3:05 pm
by Mijikai
Another (insane) way:

Code: Select all

Procedure.s GetCPUSerialNumber()
  Protected *mem
  Protected serial.i
  *mem = VirtualAlloc_(#Null,$20,#MEM_COMMIT|#MEM_RESERVE,#PAGE_EXECUTE_READWRITE)
  If *mem
    PokeQ(*mem,$48A20F80000003B8)
    PokeQ(*mem + $8,$094820E0C148D089)
    PokeW(*mem + $10,$C3C8)
    serial = CallFunctionFast(*mem)
    VirtualFree_(*mem,#Null,#MEM_RELEASE)
    ProcedureReturn Hex(serial,#PB_Quad)
  EndIf
  ProcedureReturn #Null$
EndProcedure

Re: help converting inline assembly to C-backend

Posted: Wed Jan 25, 2023 10:33 pm
by idle
Quite illustrative. I can see 48? cpuid 80000003 mov in first pokeQ

Re: help converting inline assembly to C-backend

Posted: Wed Jan 25, 2023 11:26 pm
by mk-soft
Sinclair ZX81 Hexcode Assembler :mrgreen:

Re: help converting inline assembly to C-backend

Posted: Thu Jan 26, 2023 5:02 am
by juergenkulow

Code: Select all

; Disasm CPUID 0x80000003 CPU Brand String Part 2 
*mem=AllocateMemory(20)
PokeQ(*mem,$48A20F80000003B8)
PokeQ(*mem + $8,$094820E0C148D089)
PokeW(*mem + $10,$C3C8)

Text$ = "use64" + Chr(13)  
If ExamineAssembly(*mem, *mem+18)
  While NextInstruction()
    ;Text$ + RSet(Hex(InstructionAddress()), SizeOf(Integer)*2, "0")+" "
    Text$ + InstructionString() + Chr(13)
  Wend
EndIf

MessageRequester("disasm", Text$)
Debug Text$
; use64
; mov eax, 0x80000003
; cpuid 
; mov rax, rdx
; shl rax, 0x20
; or rax, rcx
; ret 

Re: help converting inline assembly to C-backend

Posted: Thu Jan 26, 2023 5:14 am
by idle
ExamineAssembly passed my mind completely. :D

Re: help converting inline assembly to C-backend

Posted: Fri Jan 27, 2023 4:54 pm
by juergenkulow

Code: Select all

; Linux x64 GetBrand() ASM Example
ImportC ""
  mprotect (*pmem, pagesize.i, protect.i)
EndImport
#PROT_NONE  = 0
#PROT_READ  = 1
#PROT_WRITE = 2
#PROT_EXEC  = 4
#PROT_ALL   = #PROT_READ + #PROT_WRITE + #PROT_EXEC
Structure prozessornametype
  a.a[49]
EndStructure
Procedure.s GetBrand()
  Protected *mem
  Protected pagesize=1024
  Protected prozessorname.prozessornametype

  *mem = valloc_(pagesize)
  mprotect(*mem, pagesize, #PROT_ALL) 
  CopyMemory(?binstart,*mem,?binstop-?binstart)
  ShowMemoryViewer(*mem,57)
  CallFunctionFast(*mem,prozessorname)
  ProcedureReturn PeekS(prozessorname,-1,#PB_Ascii)

EndProcedure

Debug GetBrand()

DataSection
  binstart:
  IncludeBinary "/tmp/pn.bin"
  binstop:
EndDataSection

CompilerIf #PB_Compiler_OS<>#PB_OS_Linux Or #PB_Compiler_Processor<>#PB_Processor_x64
  CompilerError "Linux x64 only"
CompilerEndIf 
; Intel(R) Core(TM) i7 CPU       Q 740  @ 1.73GHz

; pn.bin 
; 00000000020E1000  B8 02 00 00 80 0F A2 89 07 89 5F 04 89 4F 08 89  ¸...€.¢‰.‰_.‰O.‰
; 00000000020E1010  57 0C B8 03 00 00 80 0F A2 89 47 10 89 5F 14 89  W.¸...€.¢‰G.‰_.‰
; 00000000020E1020  4F 18 89 57 1C B8 04 00 00 80 0F A2 89 47 20 89  O.‰W.¸...€.¢‰G ‰
; 00000000020E1030  5F 24 89 4F 28 89 57 2C C3                       _$‰O(‰W,Ã

; pn.asm 
; ;Prozessorname
; use64
; mov eax,$80000002
; cpuid
; mov [rdi],eax
; mov [rdi+4],ebx
; mov [rdi+8],ecx
; mov [rdi+12],edx
; mov eax,$80000003
; cpuid
; mov [rdi+16],eax
; mov [rdi+20],ebx
; mov [rdi+24],ecx
; mov [rdi+28],edx
; mov eax,$80000004
; cpuid
; mov [rdi+32],eax
; mov [rdi+36],ebx
; mov [rdi+40],ecx
; mov [rdi+44],edx
; ret

; kulow@kulow-G73Jw:/media/ramdisk/purebasic/compilers$ ./fasm /tmp/pn.asm