VC6中内嵌汇编的问题 __ASM{} ?

时间:2023-01-21 04:05:41
VC6中支持内嵌汇编
  如:
 
long double Hypot(long double x,long double y)
{
  __asm
   {
      fld   x
      fmul  st,st(0)
      fld   y
      fmul  st,st(0)
      faddp st(1),st
      fsqrt
    }
}
    // 该函数完成z=sqrt(x*x+y*y)功能

在Delphi中支持全汇编的函数(和过程)
但在VC6中我想写一个全汇编的函数,应该怎样办啊!
上面的程序vc6编译时会形成一些接口指令:  
   PUSH  ebp
   mov   ebp,esp
   .......

   接口部分和出口部分还有很多不必要的指令,我想自己来形成接口部分,望高手指教!

13 个解决方案

#1


>>接口部分和出口部分还有很多不必要的指令,我想自己来形成接口部分
不同意你的看法,在这种情况下可能是不必要的,但是如果你将这些接口的指令去掉,可能造成对外部环境的影响和破坏,(未必是改动,可能是某种约定),尤其可能对其它不可预料的调用者或被调用者产生伤害,除非你自己在写操作系统或底层库,不然你就不应该成为协定的改变者(接口只是其中一部分),而应该作为遵守者。
一种很危险的想法。

#2


to :glassshark(glassshark)
 vc6的调用约定是固定的(可以声明函数调用约定如stdcall),完全可以自己形成接口部分,只要按约定就可以了,并不会破坏C或系统

#3


请教一下:

    如果两个函数,只有行参不一样的,能否用汇编实现?

#4


汇编无所不能!!!
但现在VC好像不支持全汇编函数,这应该向Delphi学习

#5


你直接用汇编写不就行了,本来vc就不是用来写汇编的,你这不是强人所难吗?

#6


进口主要是保存现场,出口则是恢复现场,和返回值。
调用协议的不同有时还要考虑清栈。

#7


非也,非也。

#8


to: housisong(侯子)
》》接口部分和出口部分还有很多不必要的指令,我想自己来形成接口部分,
》》望高手指教
你没看清他说的,难道他说自己来形成接口部分也是“vc6的调用约定是固定的(可以声明函数调用约定如stdcall),完全可以自己形成接口部分,只要按约定就可以了,并不会破坏C或系统”,文不对题。

#9


如果全部用汇编写,应该怎样写汇编单元?

#10


如果全部用汇编写,就失去了用内嵌式汇编的意义,不如用汇编写一个函数再链接进来更方便些,省得把时间都浪费在这些研究编译接规则的问题上。

#11


怎样链接汇编函数啊

#12


可以单独写一个.asm文件,用tasm-->.obj,再连到.exe中

#13


我在别的社区发过这贴
我COPY过来MASM   5.1以上与C混合编程的程序头 

.MODEL SMALL,C ;小模式,用于从C调用 
.CODE 
.STACK ;如只给C调用可以不用 
EXTERN   _Cprog:    NEAR  ;同上 
EXTERN ans:  DWORD     ;说明ans是long int 的变量 

PUBLIC Cfuncion ;说明能被C调用 
Cfuncion PROC USES si   di,x:WORD,y:WORD ;如果要被C调用而有二个参数时 
LOCAl u   ;说明局部变量  如果要被C调用时用要用局部变量时说明 
;寄存器自动保存 
MOV AX,WORD PTR [BP+2] ;==X    这是SMALL模式如是中模式和  

;大模式第一个参数在[BP+4] 
ADD AX,WORD PTR [BP+4]    ;===X+Y  是第二个参数 因前一个参数是 
;int  加2个地址 
;如果数据是long  int 加4个地址 long double加8个地址  ***注意寄存器的使用char  
;加一个地址 
MOV    WORD PTR [BP-2], AX ;U===X+Y,U 是局部变量必须 
;是[BP-2]; 
;如果这时返回C这时可以不用因为返回值在AX中 
;说明C调用ASM有返回值是int或charASM把值放在AX中就可以了以后是C内部的事 
;如返回值是 long  int  ASM把值放在AX,  BX中 
;如返回值是 long  double 
ASM把值放在AX,BX,CX,DX中 
;如果ASM调用C时有返回值时 
;ASM也是从这几个寄存器中取值 
;以上说明了全部C和ASM数据接口 

;用户程序 
;******************************************************** 

;以下是ASM调用C函数的说明 
MOV    AX,421 
PUSH AX         ;压常数 fact3 
PUSH imax          ;压变量  fact2 
LEA   AX,xval 
PUSH    AX ;压入变量地址  fact 
CALL    _Cprog ;调用C程序 
ADD  SP, 6 ;现在是三个参数全是WORD所以是6 (恢复堆栈用) 
MOV ans,AX ;如象C调用    ans=Cprog(  );  
MOV ans+2,DX ; 调用结果  (是LONG型) 
;如是指针调用要用多值变化,而且还要用返回值时在定义C和ASM参数时多设一个空参数 
;以保存调用结果(但这不是必要的只要你记住SP的状态包括  ADD  SP,6)对内存的操作 
;是ASM的长处如PUSH   AX    PUSH  BX ........POP  DX  POP  AX 有必要时SP可以这 
;样使用 

;************************************************************************* 

;寄存器自动恢复 
ret 
Cfuncion ENDP 
END 

;******************************************************************************* 
;C中原型说明 
;long    Cprog(int    *fact,int   fact2,int fact3); 


;以上这ASM程序头可以根据需要修改应用于 
;ASM调用C或C调用ASM以及有参调用和过和调用 




#1


>>接口部分和出口部分还有很多不必要的指令,我想自己来形成接口部分
不同意你的看法,在这种情况下可能是不必要的,但是如果你将这些接口的指令去掉,可能造成对外部环境的影响和破坏,(未必是改动,可能是某种约定),尤其可能对其它不可预料的调用者或被调用者产生伤害,除非你自己在写操作系统或底层库,不然你就不应该成为协定的改变者(接口只是其中一部分),而应该作为遵守者。
一种很危险的想法。

#2


to :glassshark(glassshark)
 vc6的调用约定是固定的(可以声明函数调用约定如stdcall),完全可以自己形成接口部分,只要按约定就可以了,并不会破坏C或系统

#3


请教一下:

    如果两个函数,只有行参不一样的,能否用汇编实现?

#4


汇编无所不能!!!
但现在VC好像不支持全汇编函数,这应该向Delphi学习

#5


你直接用汇编写不就行了,本来vc就不是用来写汇编的,你这不是强人所难吗?

#6


进口主要是保存现场,出口则是恢复现场,和返回值。
调用协议的不同有时还要考虑清栈。

#7


非也,非也。

#8


to: housisong(侯子)
》》接口部分和出口部分还有很多不必要的指令,我想自己来形成接口部分,
》》望高手指教
你没看清他说的,难道他说自己来形成接口部分也是“vc6的调用约定是固定的(可以声明函数调用约定如stdcall),完全可以自己形成接口部分,只要按约定就可以了,并不会破坏C或系统”,文不对题。

#9


如果全部用汇编写,应该怎样写汇编单元?

#10


如果全部用汇编写,就失去了用内嵌式汇编的意义,不如用汇编写一个函数再链接进来更方便些,省得把时间都浪费在这些研究编译接规则的问题上。

#11


怎样链接汇编函数啊

#12


可以单独写一个.asm文件,用tasm-->.obj,再连到.exe中

#13


我在别的社区发过这贴
我COPY过来MASM   5.1以上与C混合编程的程序头 

.MODEL SMALL,C ;小模式,用于从C调用 
.CODE 
.STACK ;如只给C调用可以不用 
EXTERN   _Cprog:    NEAR  ;同上 
EXTERN ans:  DWORD     ;说明ans是long int 的变量 

PUBLIC Cfuncion ;说明能被C调用 
Cfuncion PROC USES si   di,x:WORD,y:WORD ;如果要被C调用而有二个参数时 
LOCAl u   ;说明局部变量  如果要被C调用时用要用局部变量时说明 
;寄存器自动保存 
MOV AX,WORD PTR [BP+2] ;==X    这是SMALL模式如是中模式和  

;大模式第一个参数在[BP+4] 
ADD AX,WORD PTR [BP+4]    ;===X+Y  是第二个参数 因前一个参数是 
;int  加2个地址 
;如果数据是long  int 加4个地址 long double加8个地址  ***注意寄存器的使用char  
;加一个地址 
MOV    WORD PTR [BP-2], AX ;U===X+Y,U 是局部变量必须 
;是[BP-2]; 
;如果这时返回C这时可以不用因为返回值在AX中 
;说明C调用ASM有返回值是int或charASM把值放在AX中就可以了以后是C内部的事 
;如返回值是 long  int  ASM把值放在AX,  BX中 
;如返回值是 long  double 
ASM把值放在AX,BX,CX,DX中 
;如果ASM调用C时有返回值时 
;ASM也是从这几个寄存器中取值 
;以上说明了全部C和ASM数据接口 

;用户程序 
;******************************************************** 

;以下是ASM调用C函数的说明 
MOV    AX,421 
PUSH AX         ;压常数 fact3 
PUSH imax          ;压变量  fact2 
LEA   AX,xval 
PUSH    AX ;压入变量地址  fact 
CALL    _Cprog ;调用C程序 
ADD  SP, 6 ;现在是三个参数全是WORD所以是6 (恢复堆栈用) 
MOV ans,AX ;如象C调用    ans=Cprog(  );  
MOV ans+2,DX ; 调用结果  (是LONG型) 
;如是指针调用要用多值变化,而且还要用返回值时在定义C和ASM参数时多设一个空参数 
;以保存调用结果(但这不是必要的只要你记住SP的状态包括  ADD  SP,6)对内存的操作 
;是ASM的长处如PUSH   AX    PUSH  BX ........POP  DX  POP  AX 有必要时SP可以这 
;样使用 

;************************************************************************* 

;寄存器自动恢复 
ret 
Cfuncion ENDP 
END 

;******************************************************************************* 
;C中原型说明 
;long    Cprog(int    *fact,int   fact2,int fact3); 


;以上这ASM程序头可以根据需要修改应用于 
;ASM调用C或C调用ASM以及有参调用和过和调用