旧文备份: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:windowssystem32目录下,在工程中,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

原文地址:https://www.cnblogs.com/winshton/p/4897935.html