zoukankan      html  css  js  c++  java
  • 旧文备份: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

  • 相关阅读:
    清除3389远程桌面连接记录的批处理
    Visual Studio Team Foundation Server 2013
    Build fast jar 打包,增加配置文件
    Asp.net MVC 出现“Failed to map the path '/'.”错误
    Java创建AD(Active Directory)域控制器用户 (未测)
    JSP/java 执行创建批处理文件,并执行批处理事务。
    域控密码策略
    项目感悟
    IE版本的标准定义
    VS编译后事件
  • 原文地址:https://www.cnblogs.com/winshton/p/4897935.html
Copyright © 2011-2022 走看看