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
遇到的问题
-
书中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