2019-01-08 (一)C语言和Intel汇编混合编程demo

foo.asm

extern choose                           ;C语言中的函数 int choose(int a,int b)
[section .data]                         ;数据段
num1st      dd      3                   ;参数a
num2nd      dd      4                   ;参数b

[section .text]                         ;代码段
global      _start                      ;程序起点
global      myprint                     ;输出函数
_start:
            push    dword   [num2nd]    ;将参数入栈
            push    dword   [num1st]
            call    choose              ;调用C语言函数
            add     esp,    8

            mov     ebx,    0
            mov     eax,    1           ;sys_exit
            int     0x80                ;系统调用

myprint:
            mov     edx,    [esp+8]     ;len    
            mov     ecx,    [esp+4]     ;msg
            mov     ebx,    1               
            mov     eax,    4           ;sys_write
            int     0x80                ;系统调用
            ret      
         

bar.c

void myprint(char *msg,int len);    //foo.asm中的myprint

int choose(int a,int b){    
    if(a>=b){
        myprint("1\n",3);
    }else{
        myprint("2\n",3);
    }
    return 0;
}

编译命令

nasm -f elf -o foo.o foo.asm 
gcc -m32 -c -o bar.o bar.c
ld -m elf_i386 -s -o foobar foo.o bar.o 
./foobar 

输出

2

遇到的问题

  1. 书中ld -s -o foobar foo.o bar.o 报错:ld: i386 架构于输入文件 foo.o 与 i386:x86-64 输出不兼容

    产生原因:因为运行书中的

    gcc -c -o bar.o bar.c
    

    默认在64位的机器上默认生成64位的目标代码,而nasm生成的是32位目标代码,两者无法链接

    解决方案:

    使gcc编译32位目标代码

    gcc -m32 -c -o bar.o bar.c
    

    链接时加上32位的选项

    ld -m elf_i386 -s -o foobar foo.o bar.o  
    

你可能感兴趣的:(2019-01-08 (一)C语言和Intel汇编混合编程demo)