C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 Q&A
C++Builder Programming Q&A
[6184] Re:[급질문]CYRIX CPU 정보 알아내는 소스인데 ASM으로 된 함수를 참조 하는 방법 좀 가르쳐주세여.
최혜원.시리 [sirius] 2539 읽음    2001-03-19 14:10
asm으로 된 함수의 앞에 asm 으로 붙이고 사용하세요..
그리고 콜하는 부분은 함수로 처리하시고요..
한가지 예를 드리면 다음과 같습니다.

unsigned char inportb(unsigned short int port)
{
   unsigned char value;
   asm mov dx, port;      // asm 을 붙인 것을 알 수 있지요??
   asm in al, dx;
   asm mov value, al;
   return value;
}

즐거운 하루 되세요..
-----------------------------------------------------------------------------------------

허접푸케케 님이 쓰신 글 :
: 데브피아에서.. CYRIX CPU 정보 알아내는 소스를 구했는데여....
: C와 asm 으로 되어있는데...asm으로 된 함수를 콜하는 부분이 있는데..
: Cbuilder에서 어떻게 사용해야 하나여...
: 넘 초보라.....어찌 해야할지 모르겠네여...
: 넘 개념없는 질문이라....고생스럽더라도...ㅠ.ㅠ
:
: /* ..................................................................... */
: /* includes                                                              */
: /* ..................................................................... */
: #include <string.h>
: #include "cyrix.h"
: #include "cpu_type.h"
: #include "cpu_mhz.h"
:
: /* ..................................................................... */
: /* implemention functions prototypes                                     */
: /* ..................................................................... */
:
: /* Used for cpu_type */
: #define Cx486        0x1  
: #define _5x86        0x2
: #define MediaGX      0x3
: #define _6x86        0x4
: #define _6x86MX      0x5
:
:
: /* .ASM functions used */
: int isfpu (void);
: int iscyrixfpu (void);
: int is_cpuid_supported (void);
: int oldiscyrix (void);
: int is486(void);
: int isv86(void);
: char cx_r (char);
: void cx_w (char, char);
: unsigned long cpu_speed( unsigned int );
: void read_time_stamp( unsigned long *v1, unsigned long *v2 );
: void get_cpuid_info (long v1, long *v2, long *v3, long *v4, long *v5);
:
:
: /* functions used internally only */
: static unsigned short Get_DIRs(char *, char *);
: static void NameByDIRs (unsigned char, unsigned char, char* );
: static void Set_Features(unsigned char, unsigned char, CPUInfo* );
: static int cpu_type(void);
:
:
:
:
: //Cyrixasm.asm 파일-------------------------------------------------------------------------public _is_cpuid_supported
: public _get_cpuid_info
: public _extended_cpuid_supported
: public _oldiscyrix
: public _iscyrixfpu
: public _is486
: public _isfpu
: public _isv86
: public _cx_r
: public _cx_w
: public _read_time_stamp
: public _cpu_speed
:
: assume  cs:_TEXT
:
: rdtsc macro
:         db 0fh, 031h
: endm
:
: _TEXT   segment byte public 'CODE'
:
: ;**************************************************************************   
: ;       Function:    int is_cpuid_supported ()
: ;
: ;       Purpose:        Check for existence of CPUID instruction.
: ;                       If exists execute CPUID with eax==0.
: ;
: ;       Inputs:         none
: ;                      
: ;       Output:        
: ;                      
: ;       Returns:        0 - no CPUID instruction supported
: ;                       1 - CPUID instruction supported
: ;**************************************************************************
:
: cpuid macro
:         db 0fh, 0a2h
: endm
:
: _is_cpuid_supported        proc    near
: .386
:         pushfd                  ; save current flags
:         push    eax
:         push    ebx
:
:         pushfd                  ; get extended flags
:         pop     eax
:         mov     ebx, eax        ; save current flags
:
:         xor     eax, 200000h    ; toggle bit 21
:         push    eax             ; put new flags on stack
:         popfd                   ; flags updated now in flags
:
:         pushfd                  ; get extended flags
:         pop     eax            
:         xor     eax, ebx        ; if bit 21 r/w then eax <> 0
:
:         pop     ebx
:         pop     eax
:
:         je      no_cpuid        ; can't toggle id bit (21) no cpuid here
:
:         mov     eax, 1          ; cpuid supported
:
:         jmp     done_cpuid_sup
:
: no_cpuid:
:         mov     eax, 0          ; cpuid not supported
:
: done_cpuid_sup:
:         popfd                   ; restore original flags
:     ret
: _is_cpuid_supported        endp
:
: ;**************************************************************************   
: ;       Function:       void get_cpuid_info (long level,
: ;                                            long R_eax,
: ;                                            long R_ebx,
: ;                                            long R_ecx,
: ;                                            long R_edx)
: ;
: ;       Purpose:        Execute CPUID instruction at level (eax==level)
: ;
: ;       Inputs:         level - eax value when CPU is executed
: ;                      
: ;       Output:         reg_eax - eax after executing CPUID
: ;                       reg_ebx - ebx after executing CPUID
: ;                       reg_ecx - ecx after executing CPUID
: ;                       reg_edx - edx after executing CPUID
: ;**************************************************************************
: _get_cpuid_info        proc    near
: .386
:     push    bp
:     mov    bp, sp
:
:         push    eax
:         push    ebx
:         push    ecx
:         push    edx
:         push    esi
:
:     mov    eax, dword ptr [bp+4]      ; get level
:
:         cpuid                  
:
:     mov    si,word ptr [bp+8]
:     mov    dword ptr [si],eax        ; reg_eax := eax
:
:     mov    si,word ptr [bp+10]
:     mov    dword ptr [si],ebx        ; reg_ebx := ebx
:
:         mov    si,word ptr [bp+12]       ; reg_ecx := ecx
:     mov    dword ptr [si],ecx
:
:         mov    si,word ptr [bp+14]       ; reg_edx := edx
:     mov    dword ptr [si],edx
:
:         pop     esi
:         pop     edx
:         pop     ecx
:         pop     ebx
:         pop     eax
:
:         mov     sp,bp
:         pop     bp
:     ret
: _get_cpuid_info        endp
:
:
: ;**************************************************************************   
: ;       Function:       int extended_cpuid_supported
: ;
: ;       Purpose:        Determine if ExtendedCPUID is supported
: ;       Technique:      Do CPUID with eax = 8000 0000, if eax returns a
: ;                        value greater than 1, then it is supported
: ;       Inputs:         none
: ;       Output:         ax == 1 ExtendedCPUID supported, 0 if not
: ;**************************************************************************
:
: _extended_cpuid_supported       proc near
:
: .386
:         mov     eax, 80000000h  ; try extended CPUID
:         cpuid                  
:
:         cmp     eax, 1          ; eax > 1
:         jle     no_ecpuid
:
:         mov     eax, 1          ; extended cpuid supported
:         jmp     done_ecpuid
:
: no_ecpuid:
:         mov     eax, 0          ; extended cpuid not supported
:
: done_ecpuid:
:     ret
: _extended_cpuid_supported        endp
:
:
: ;**************************************************************************   
: ;       Function:       int oldiscyrix ()
: ;
: ;       Purpose:        Determine if Cyrix CPU is present via 5/2 method
: ;       Technique:      Cyrix CPUs do not change flags where flags change
: ;                        in an undefined manner on other CPUs
: ;       Inputs:         none
: ;       Output:         ax == 1 Cyrix present, 0 if not
: ;**************************************************************************
: _oldiscyrix   proc near
:         push  bx
:         xor   ax, ax         ; clear ax
:         sahf                 ; clear flags, bit 1 is always 1 in flags
:         mov   ax, 5         
:         mov   bx, 2
:         div   bl             ; do an operation that does not change flags
:         lahf                 ; get flags
:         cmp   ah, 2          ; check for change in flags
:         jne   not_cyrix1     ; flags changed not Cyrix       
:         mov   ax, 1          ; TRUE Cyrix CPU
:         jmp   done1
:
: not_cyrix1:
:         mov  ax, 0           ; FALSE NON-Cyrix CPU
: done1:
:         pop  bx
:         ret
: _oldiscyrix   endp
:
: ;**************************************************************************   
: ;       Function:       int iscyrixfpu()   
: ;       Technique:
: ;               On both the Cyrix and Intel math coprocessor the function
: ;               2^x-1 is undefined when its argument does not lie between
: ;               -1 and +1. Therefore, when this function is evaluated at
: ;               x=pi it is not surprising that the answers returned by the
: ;               Cyrix and Intel chips are distinct.  This program computes
: ;               2^PI-1 and stores the result as a single precision number
: ;               VALUE.  It is possible to distinguish between the Cyrix and
: ;               Intel math coprocessors by comparing VALUE with the known
: ;               value obtained when using a Cyrix or Intel math coprocessor.
: ;
: ;       Purpose:        Determine if Cyrix FPU is present
: ;       Inputs:         None
: ;       Output:         AX=1 if Cyrix FPU Present else AX=0
: ;**************************************************************************
:
: _iscyrixfpu    proc    near
:     push    bp
:     mov    bp,sp
:     sub    sp,4                    ; get stack space
:     push    si                      ; use as temp
:
:     finit                            ; inialize fpu
:     fldpi                            ; fpu loads pi
:     f2xm1                            ; 2^pi - 1
:     fstp    dword ptr [bp-4]        ; store computed value
:
:     lea    si, word ptr [bp-2]     ; get address of stored value
:     cmp    word ptr [si], 3FC9h    ; compare stored value to Cyrix
:         jne     short not_cyrix2
:     mov    ax, 1                   ; True Cyrix FPU present
:         jmp     short done2
:
: not_cyrix2:
:     mov    ax, 0                   ; FALSE Cyrix FPU not present
:
: done2:
:     pop    si
:     mov    sp,bp
:     pop    bp
:     ret   
: _iscyrixfpu    endp
:
: ;**************************************************************************   
: ;       Function:    is486 ()
: ;
: ;       Purpose:        Check for presence of a 486 level support.
: ;
: ;       Returns:        1 if 486 or better present.
: ;                       0 if earlier than a 486 is present.
: ;                      
: ;**************************************************************************
:
: _is486  proc near
:
:         .486
:     pushfd            ; save EFLAGS
:
:     pop    eax        ; get EFLAGS
:     mov    ecx, eax    ; temp storage EFLAGS
:     xor    eax, 1 SHL 18    ; change AC bit in EFLAGS
:        
:     push    eax        ; put new EFLAGS value on stack
:     popfd            ; replace current EFLAGS value
:
:     pushfd            ; get EFLAGS
:     pop    eax        ; save new EFLAGS in EAX
:     cmp    eax, ecx    ; compare temp and new EFLAGS
:
:         jz      is_not_80486
:     mov    ax, 1            ; 80486 present
:         jmp     done3
:
: is_not_80486:       
:         mov     ax, 0           ; 80486 not present
:
: done3:
:     push    ecx             ; get original EFLAGS
:     popfd            ; restore EFLAGS
:         ret
:
: _is486  endp
:
: ;**************************************************************************   
: ;       Function:    isfpu ()
: ;
: ;       Purpose:        Determine if FPU is present
: ;       Inputs:         None
: ;       Output:         ax=1 if FPU present, 0 otherwise
: ;**************************************************************************
: _isfpu proc near
:         .386
:         .387
:         fninit
:         mov     ax, 5a5ah
:         fnstsw  ax
:         cmp     ax, 0
:         jne     no_fpu
:         mov     ax, 1
:         jmp     done4
:
: no_fpu:       
:         mov     ax, 0
: done4:
:         ret
:
: _isfpu  endp
:
: ;**************************************************************************   
: ;       Function:    isv86()
: ;
: ;       Purpose:        Determine if CPU is in REAL or V86
: ;       Technique:      Check PE bit.  If set then assume V86.
: ;                       *** Note ***  This technique only works
: ;                                     for distinguishing V86 vs REAL.
: ;                                     IT does not hold for anything else!
: ;       Inputs:         none
: ;       Output:         ax == 1 in V86 mode, else 0
: ;**************************************************************************
:
: _isv86 proc near
:         .486P
:         smsw    ax
:         test    al, 1
:         jz      no_v86
:         mov     ax, 1
:         jmp     done5
:
: no_v86:       
:         mov     ax, 0
: done5:
:         ret
:
: _isv86  endp
:
: ;**************************************************************************   
: ;       Function:    char cx_r (char index)
: ;
: ;       Purpose:        Reads Cyrix Configuration Register at index
: ;       Inputs:         byte index, Cyrix Configuration Register
: ;       Output:         al, Contents of Cyrix Configuration Register
: ;**************************************************************************
: _cx_r    proc    near
:     push    bp
:     mov    bp,sp
:         pushf                           ; save flags
:         cli                             ; clear interrupt in flags
:     mov    al, byte ptr [bp+4]     ; get index
:     out    22h, al                 ; tell CPU which config. register
:     in    al, 23h                 ; write to CPU config. register
:         popf                            ; restore flags
:     mov    sp,bp
:     pop    bp
:     ret   
: _cx_r    endp
:
: ;**************************************************************************   
: ;       Function:    void cx_w (char index, char val)
: ;
: ;       Purpose:        Write Cyrix Configuration Register at index with val
: ;       Inputs:         byte index, Cyrix Configuration Register
: ;                       byte val, value to be written to index
: ;       Output:         nothing
: ;**************************************************************************
: _cx_w    proc    near
:     push    bp
:     mov    bp,sp
:         pushf                           ; save flags
:         cli                             ; clear interrupt in flags
:     mov    al, byte ptr [bp+4]     ; get index
:         out    22h, al                 ; tell CPU which config. register
:     mov    al, byte ptr [bp+6]     ; get val
:     out    23h, al                 ; write to CPU config. register
:         popf                            ; restore flags
:     mov    sp,bp
:     pop    bp
:     ret   
: _cx_w    endp
:
: .386p
: ;***********************************************************************
: ; Function:     void read_time_stamp( long*, long* );
: ; Purpose:      read Time Stamp Counter
: ;
: ; Inputs:       pointers to two longs
: ;               Param1 = Upper DWord
: ;               Param2 = Lower DWord
: ; Returns:      values of Time Stamp Counter
: ;
: ; NOTE:         You must check for TSC before using this function!!!
: ;***********************************************************************
:
: _read_time_stamp proc near
:     push    bp
:     mov    bp, sp
:
:         push    eax                       ; save off values
:         push    edx
:         push    si
:        
:         rdtsc                             ; db 0fh, 031h
:
:         mov     si,word ptr [bp+4]
:         mov     dword ptr [si],edx        ; param 1 = edx (Upper DWord)
:
:         mov     si,word ptr [bp+6]
:         mov     dword ptr [si],eax        ; param 2 = eax (Lower DWord)
:
:         pop     si                        ; restore old values
:         pop     edx
:         pop     eax
:
:         mov     sp,bp
:         pop     bp
:     ret
: _read_time_stamp endp
:
: ;***********************************************************************
: ; Function:     unsigned long _cpu_speed( unsigned int )
: ;               "C" style caller
: ; Purpose:      calculate the elapsed time req'd to complete a loop of IDIVs
: ;
: ; Technique:    Use the PC's high resolution timer/counter chip (the 8254)
: ;               to measure elapsed time of a software loop consisting
: ;               of the IDIV and LOOP instruction.
: ; Definitions:  The 8254 recieves a 1.19318MHz clock (0.8380966 usec).
: ;               One "tick" is equal to one rising clock edge applied
: ;               to the 8254 clock input.
: ;
: ; Inputs:       ax = no. of loops for cpu_speed_loop
: ; Returns:      ax = no. of 1.19318MHz clk ticks req'd to complete the loop
: ;               dx = state of 8254 out pin
: ;***********************************************************************
:
: PortB           EQU     061h
: Timer_Ctrl_Reg  EQU     043h
: Timer_2_Data    EQU     042h
: stk$dx          EQU     10              ;dx register offset
: stk$ax          EQU     14              ;ax register offset
: stack$ax        EQU     [bp]+stk$ax
: stack$dx        EQU     [bp]+stk$dx
: Loop_Count      EQU     [bp+16]+4
:
: _cpu_speed      proc near
:         pushf                          ;save interrupt flag
:         pusha                          ;pushes 16 bytes on stack
:         mov     bp,sp                  ;init base ptr
:
:         cli                            ;disable interrupts
:
: ;-------disable clock to timer/counter 2
:         in      al, PortB
:         and     al, NOT (1 SHL 0)      ; clear bit 0
:         out     PortB, al
:         mov     di, ax
:
: ;-------initialize the 8254 counter to "0", known value
:         mov     al,0b0h
:         out     Timer_Ctrl_Reg, al     ;control word to set channel 2 count
:         mov     al,0ffh
:         out     Timer_2_Data, al       ;init count to 0, lsb
:         out     Timer_2_Data, al       ;init count to 0, msb
:
: ;-------get the number of loops from the caller's stack
:         mov     cx,Loop_Count          ;loop count
:
: ;-------load dividend and divisor, clk count for IDIV depend on operands!
:         xor     edx,edx                 ;dividend EDX:EAX
:         xor     eax,eax
:         mov     ebx,1                   ;divisor
:
: ;-------enable the timer/counter's clock. Begin timed portion of test!
:         xchg    ax, di                  ;save ax for moment
:         or      al, 1
:         out     PortB, al               ;enable timer/counter 2 clk
:         xchg    ax, di                  ;restore ax
:
: ;-------skip loop if Loop_Count = 0
:         cmp     cx, 0
:         jz      after_loop
:
: ;-------this is the core loop.
: ;        ALIGN 2                         ; This should really be ALIGN 16
: cpu_speed_loop:
:         idiv    ebx
:         idiv    ebx
:         idiv    ebx
:         idiv    ebx
:         idiv    ebx
:         loop    cpu_speed_loop
:
: after_loop:
: ;-------disable the timer/counter's clk.  End timed portion of test!
:         mov     ax, di
:         and     al, NOT (1 SHL 0)      ; clear bit 0
:         out     PortB, al
:
: ;-------send latch status command to the timer/counter
:         mov     al, 0c8h                ;latch status and count
:         out     Timer_Ctrl_Reg, al
:
: ;-------read status byte, and count value "ticks" from the timer/cntr
:         in      al, Timer_2_Data        ;read status
:         mov     dl, al
:         and     dx, 080h
:         shr     dx, 7                   ; bit 0 = state of 8254 output pin
:
:         in      al, Timer_2_Data        ;read LSB
:         mov     bl, al
:         in      al, Timer_2_Data        ;read MSB
:         mov     bh, al
:
:         not     bx                      ;invert count
:
: ;-------send command to clear the timer/counter
:         mov     al, 0b6h
:         out     Timer_Ctrl_Reg, al      ;clear channel 2 count
:         xor     al, al
:         out     Timer_2_Data, al        ;set count to 0, lsb
:         out     Timer_2_Data, al        ;set count to 0, msb
:
: ;-------put return values on the stack for the caller
:         mov     [bp+stk$ax], bx
:         mov     [bp+stk$dx], dx
:
:         popa
:         popf                            ;restores interrupt flag
:         ret
: _cpu_speed      endp
:
: _TEXT    ends
:
: end
:

+ -

관련 글 리스트
6179 [급질문]CYRIX CPU 정보 알아내는 소스인데 ASM으로 된 함수를 참조 하는 방법 좀 가르쳐주세여. 허접푸케케 2257 2001/03/19
6200     Re:[급질문]CYRIX CPU 정보 알아내는 소스인데 ASM으로 된 함수를 참조 하는 방법 좀 가르쳐주세여. 박세용 2339 2001/03/19
6184     Re:[급질문]CYRIX CPU 정보 알아내는 소스인데 ASM으로 된 함수를 참조 하는 방법 좀 가르쳐주세여. 최혜원.시리 2539 2001/03/19
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.