如:
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或系统
vc6的调用约定是固定的(可以声明函数调用约定如stdcall),完全可以自己形成接口部分,只要按约定就可以了,并不会破坏C或系统
#3
请教一下:
如果两个函数,只有行参不一样的,能否用汇编实现?
如果两个函数,只有行参不一样的,能否用汇编实现?
#4
汇编无所不能!!!
但现在VC好像不支持全汇编函数,这应该向Delphi学习
但现在VC好像不支持全汇编函数,这应该向Delphi学习
#5
你直接用汇编写不就行了,本来vc就不是用来写汇编的,你这不是强人所难吗?
#6
进口主要是保存现场,出口则是恢复现场,和返回值。
调用协议的不同有时还要考虑清栈。
调用协议的不同有时还要考虑清栈。
#7
非也,非也。
#8
to: housisong(侯子)
》》接口部分和出口部分还有很多不必要的指令,我想自己来形成接口部分,
》》望高手指教
你没看清他说的,难道他说自己来形成接口部分也是“vc6的调用约定是固定的(可以声明函数调用约定如stdcall),完全可以自己形成接口部分,只要按约定就可以了,并不会破坏C或系统”,文不对题。
》》接口部分和出口部分还有很多不必要的指令,我想自己来形成接口部分,
》》望高手指教
你没看清他说的,难道他说自己来形成接口部分也是“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以及有参调用和过和调用
我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或系统
vc6的调用约定是固定的(可以声明函数调用约定如stdcall),完全可以自己形成接口部分,只要按约定就可以了,并不会破坏C或系统
#3
请教一下:
如果两个函数,只有行参不一样的,能否用汇编实现?
如果两个函数,只有行参不一样的,能否用汇编实现?
#4
汇编无所不能!!!
但现在VC好像不支持全汇编函数,这应该向Delphi学习
但现在VC好像不支持全汇编函数,这应该向Delphi学习
#5
你直接用汇编写不就行了,本来vc就不是用来写汇编的,你这不是强人所难吗?
#6
进口主要是保存现场,出口则是恢复现场,和返回值。
调用协议的不同有时还要考虑清栈。
调用协议的不同有时还要考虑清栈。
#7
非也,非也。
#8
to: housisong(侯子)
》》接口部分和出口部分还有很多不必要的指令,我想自己来形成接口部分,
》》望高手指教
你没看清他说的,难道他说自己来形成接口部分也是“vc6的调用约定是固定的(可以声明函数调用约定如stdcall),完全可以自己形成接口部分,只要按约定就可以了,并不会破坏C或系统”,文不对题。
》》接口部分和出口部分还有很多不必要的指令,我想自己来形成接口部分,
》》望高手指教
你没看清他说的,难道他说自己来形成接口部分也是“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以及有参调用和过和调用
我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以及有参调用和过和调用