旧文备份:VC中嵌入NASM编写的汇编函数
在公司开发的RT下没法使用C库,并且替代库函数没有几个,需要用到setjmp和longjmp函数,没办法,只能自己想办法了,上sourceforge淘换到一个小日本的工程,提供这两个函数的替代源码,名字叫libcont,下载下来发现实在Linux下编译的,查看Makefile文件,使用了GCC和NASM,郁闷了,但是实在找不到windows下的代码了,看看能不能移植到VC下吧!
千辛万苦,本想修改代码移植到VC下,无奈汇编格式差异较大,后经同事提醒,在VS2005下调用NASM总算把汇编嵌进来了,下面把步骤记录下来:
1.查看源文件,发现跟setjmp有关的有四个文件,分别是mysetjmp.h mysetjmp.c mysetjmp.asm macro.asm,把mysetjmp.h和mysetjmp.asm移进win32工程,mysetjmp.c不要了,其中的调用方式不适合VC。
2.sourceforge下载最新版NASM win32的那个,解压缩,将nasm.exe放到x:\windows\system32\目录下,在工程中,mysetjmp.asm上右键属性,配置属性下的自定义生成步骤,命令行参数填入:nasm -i $(InputDir) $(InputDir)$(InputName).asm -f win32 -o $(IntDir)\$(InputName).obj 调用nasm将文件编译成win32格式的obj文件,-i $(InputDir) 参数是为了找到并调用本目录下的macro.asm文件;输出填入:$(IntDir)\$(InputName).obj。
3.打开mysetjmp.asm汇编文件,发现有两个函数,_mysetjmp 和_mylongjmp;打开mysetjmp.h,发现 int _mysetjmp(myjmp_buf);void _mylongjmp(myjmp_buf, int);两个函数,正好跟汇编函数对应,现在要对这两个文件稍作修改以适应VC环境,首先去掉每个函数前面的"_"这样在链接时VC才能找到汇编的两个函数,VC就是这么定的,然后添加_stdcall 之后两个函数声明变为:
int _stdcall mysetjmp(myjmp_buf);
void _stdcall mylongjmp(myjmp_buf, int);
4.修改mysetjmp.asm文件的两个函数名,分别添加后缀@4和@8,@后面跟的数字跟传递的参数有关,_mysetjmp改为_mysetjmp@4 因传递的参数为4字节的数组指针,_mylongjmp@8就是两个参数一共8字节了。
5.好了,编译工程吧,O了;使用时包含mysetjmp.h文件就可以了,跟调用C库函数一样。
附libcont三个文件修改后的代码:
----------------------------------------------------------------------------------------------------
mysetjmp.h
----------------------------------------------------------------------------------------------------
/*************************************************************
* Copyright (c) 2006 Shotaro Tsuji
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
* THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*************************************************************/
/* Please send bug reports to
Shotaro Tsuji
4-1010,
Sakasedai 1-chome,
Takaraduka-si,
Hyogo-ken,
665-0024
Japan
negi4d41@yahoo.co.jp
*/
#ifndef _MY_SETJMP_H_
#define _MY_SETJMP_H_
#ifdef __cplusplus
extern "C" {
#endif
/*
* 銈枫偘銉娿儷銉炪偣銈劇瑕栥仐銇︺亰k锛? *
* setjmp銇с儸銈搞偣銈裤倰瑭般倎杈笺倱銇ongjmp銇у厓銇埢銇欍仹銇妅锛? * longjmp銇浜屽紩鏁般伅jmp_buf銇甧ax銇牬鎵€銇┌銈佽炯銇俱倢銈嬨倝銇椼亜銇? *
* 銉偢銈广偪涓€瑕? * EAX EBX ECX EDX ESI EDI EBP ESP EIP EFLAGS DS SS CS ES FS GS
* 32bit銉偢銈广偪16鍊? */
#define _JBLEN 16
#define _JBTYPE int
typedef _JBTYPE myjmp_buf[_JBLEN];
//#define mysetjmp _mysetjmp
//#define mylongjmp _mylongjmp
int _stdcall mysetjmp(myjmp_buf);
void _stdcall mylongjmp(myjmp_buf, int);
#ifdef __cplusplus
}
#endif
#endif
----------------------------------------------------------------------------------------------------
mysetjmp.asm
----------------------------------------------------------------------------------------------------
bits 32
;; Copyright (c) 2006 Shotaro Tsuji
section .bss
section .data
section .text
%include "macro.asm"
cglobal _mysetjmp@4
cglobal _mylongjmp@8
; jmp_buf:
; eax ebx ecx edx esi edi ebp esp eip
; 0 4 8 12 16 20 24 28 32
_mysetjmp@4: ; int _setjmp(jmp_buf env);
push ebp
mov ebp, esp
push edi ; edi銈掍繚瀛?
mov edi, dword [ebp+8] ; env銇偄銉夈儸銈广倰edi銇唬鍏?
mov dword [edi+0], eax
mov dword [edi+4], ebx
mov dword [edi+8], ecx
mov dword [edi+12], edx
mov dword [edi+16], esi
mov eax, dword [ebp-4]
mov dword [edi+20], eax
mov eax, dword [ebp]
mov dword [edi+24], eax
mov eax, esp
add eax, 12
mov dword [edi+28], eax
mov eax, dword [ebp+4]
mov dword [edi+32], eax
pop edi
mov eax, 0
leave
ret
_mylongjmp@8: ; void _longjmp(jmp_buf env, int retval);
push ebp
mov ebp, esp
mov edi, dword [ebp+8]
mov eax, dword [ebp+12]
mov dword [edi], eax
mov ebp, dword [edi+24]
;cli
mov esp, dword [edi+28]
push dword [edi+32]
mov eax, dword [edi]
mov ebx, dword [edi+4]
mov ecx, dword [edi+8]
mov edx, dword [edi+12]
mov esi, dword [edi+16]
mov edi, dword [edi+20]
;sti
ret
----------------------------------------------------------------------------------------------------
macro.asm
----------------------------------------------------------------------------------------------------
%ifdef MONA
%macro cglobal 1
global _%1
%define %1 _%1
%endmacro
%macro cextern 1
extern _%1
%define %1 _%1
%endmacro
%macro cexport 1
global _%1
export %1
%define %1 _%1
%endmacro
%else
%macro cglobal 1
global %1
%endmacro
%macro cextern 1
extern %1
%endmacro
%macro cexport 1
global %1
%endmacro
%endif