我正在尝试在x64 Debian上编译这个x86汇编代码:
BITS 32 %include 'training.s' global main extern exit ; =============================================== section .text main: ; The program begins here: call read_hex mov edx,eax call read_hex add eax,edx add eax,eax inc eax call print_eax ; Exit the process: push 0 call exit
我收到这些错误:
~$nasm -f elf -g 0_strange_calc.asm && ld -o 0_strange_calc 0_strange_calc.o ld: i386 architecture of input file `0_strange_calc.o' is incompatible with i386:x86-64 output ld: warning: cannot find entry symbol _start; defaulting to 00000000004000b0 0_strange_calc.o:training.s:25: undefined reference to `printf' 0_strange_calc.o:training.s:35: undefined reference to `printf' 0_strange_calc.o:training.s:45: undefined reference to `printf' 0_strange_calc.o:training.s:56: undefined reference to `read' 0_strange_calc.o:training.s:77: undefined reference to `scanf' 0_strange_calc.o:training.s:97: undefined reference to `scanf' 0_strange_calc.o:training.s:108: undefined reference to `printf' 0_strange_calc.o:training.s:129: undefined reference to `printf' 0_strange_calc.o:training.s:137: undefined reference to `printf' 0_strange_calc.o:0_strange_calc.asm:50: undefined reference to `exit' ~$ yasm -f elf64 0_strange_calc.asm ~$ gcc -m32 -nostdlib -nostdinc 0_strange_calc.o -o 0_strange_calc /usr/bin/ld: i386:x86-64 architecture of input file `0_strange_calc.o' is incompatible with i386 output /usr/bin/ld: warning: cannot find entry symbol _start; defaulting to 00000000080480c0 0_strange_calc.o: In function `no symbol': 0_strange_calc.asm:(.text+0x8): undefined reference to `printf' 0_strange_calc.asm:(.text+0x19): undefined reference to `printf' 0_strange_calc.asm:(.text+0x2a): undefined reference to `printf' 0_strange_calc.asm:(.text+0x39): undefined reference to `read' 0_strange_calc.asm:(.text+0x5b): undefined reference to `scanf' 0_strange_calc.asm:(.text+0x7a): undefined reference to `scanf' 0_strange_calc.asm:(.text+0x89): undefined reference to `printf' 0_strange_calc.asm:(.text+0xa8): undefined reference to `printf' 0_strange_calc.asm:(.text+0xb9): undefined reference to `printf' 0_strange_calc.o: In function `main': 0_strange_calc.asm:(.text+0xdb): undefined reference to `exit' collect2: error: ld returned 1 exit status
这是我的0_strange_calc.o转储:
~$ objdump -M intel -d 0_strange_calc.o 0_strange_calc.o: file format elf64-x86-64 Disassembly of section .text: 0000000000000000: 0: 60 (bad) 1: 50 push rax 2: 68 00 00 00 00 push 0x0 7: e8 00 00 00 00 call c c: 83 c4 08 add esp,0x8 f: 61 (bad) 10: c3 ret 11: 60 (bad) 12: 50 push rax 13: 68 00 00 00 00 push 0x0 18: e8 00 00 00 00 call 1d 1d: 83 c4 08 add esp,0x8 20: 61 (bad) 21: c3 ret 22: 60 (bad) 23: b8 00 00 00 00 mov eax,0x0 28: 50 push rax 29: e8 00 00 00 00 call 2e 2e: 83 c4 04 add esp,0x4 31: 61 (bad) 32: c3 ret 33: 60 (bad) 34: 51 push rcx 35: 57 push rdi 36: 6a 00 push 0x0 38: e8 00 00 00 00 call 3d 3d: 83 c4 0c add esp,0xc 40: 31 d2 xor edx,edx 42: c6 04 07 00 mov BYTE PTR [rdi+rax*1],0x0 46: 61 (bad) 47: c3 ret 48: 55 push rbp 49: 89 e5 mov ebp,esp 4b: 83 ec 04 sub esp,0x4 4e: 53 push rbx 4f: 51 push rcx 50: 52 push rdx 51: 8d 5d fc lea ebx,[rbp-0x4] 54: 53 push rbx 55: 68 00 00 00 00 push 0x0 5a: e8 00 00 00 00 call 5f 5f: 83 c4 08 add esp,0x8 62: 8b 03 mov eax,DWORD PTR [rbx] 64: 5a pop rdx 65: 59 pop rcx 66: 5b pop rbx 67: c9 leave 68: c3 ret 69: 55 push rbp 6a: 89 e5 mov ebp,esp 6c: 83 ec 04 sub esp,0x4 6f: 8d 5d fc lea ebx,[rbp-0x4] 72: 60 (bad) 73: 53 push rbx 74: 68 00 00 00 00 push 0x0 79: e8 00 00 00 00 call 7e 7e: 83 c4 08 add esp,0x8 81: 61 (bad) 82: 8b 03 mov eax,DWORD PTR [rbx] 84: c9 leave 85: c3 ret 86: 60 (bad) 87: 56 push rsi 88: e8 00 00 00 00 call 8d 8d: 83 c4 04 add esp,0x4 90: 61 (bad) 91: c3 ret 92: 60 (bad) 93: b9 20 00 00 00 mov ecx,0x20 98: d1 c0 rol eax,1 9a: 89 c2 mov edx,eax 9c: 83 e2 01 and edx,0x1 9f: 51 push rcx a0: 50 push rax a1: 52 push rdx a2: 68 00 00 00 00 push 0x0 a7: e8 00 00 00 00 call ac ac: 83 c4 08 add esp,0x8 af: 58 pop rax b0: 59 pop rcx b1: e2 e5 loop 98 b3: 68 00 00 00 00 push 0x0 b8: e8 00 00 00 00 call bd bd: 83 c4 04 add esp,0x4 c0: 61 (bad) c1: c3 ret 00000000000000c2 : c2: e8 81 ff ff ff call 48 c7: 89 c2 mov edx,eax c9: e8 7a ff ff ff call 48 ce: 01 d0 add eax,edx d0: 01 c0 add eax,eax d2: 40 e8 28 ff ff ff rex call 0 d8: 6a 00 push 0x0 da: e8 00 00 00 00 call df
它似乎已经在x64 asm中成功转换,我编译和链接的其他简单代码没有问题.我究竟做错了什么?我该如何解决?
你有几个选择
使用LD链接到最终的可执行文件
使用GCC链接到最终的可执行文件
您的命令行使用LD,遗憾的是,这会产生许多问题.首先:
ld:输入文件"0_strange_calc.o"的i386架构与i386不兼容:x86-6
您使用64位Debian,尝试生成32位可执行文件.-f elf
在NASM命令行上生成32位ELF(-f elf64
生成64位对象).您的LD命令行是通过默认试图生成64位的可执行从而上述错误中给出.您可以通过向LD的命令行添加选项来强制LD生成32位可执行文件.-m elf_i386
ld:警告:找不到入口符号_start; 默认为00000000004000b0
你应该告诉LD你的入口点是主要的.默认情况下,LD会查找_start的入口点.您可以添加-e main
到LD命令行来解决该问题.
像这样的错误表明你需要C库(printf存在的地方):
0_strange_calc.asm :(.text + 0x8):对`printf'的未定义引用
由于您的代码不直接使用printf,我只能假设函数需要它training.s
.要在C库中进行链接,您需要.o
在命令行中的文件之后添加它.您可以-lc
在LD命令行上执行此操作.您还需要告诉LD具体需要使用的动态链接库(在本例中为32位).在Debian环境中,通常看起来像:-dynamic-linker /lib/ld-linux.so.2
所以你的NASM和LD线应该是这样的:
nasm -f elf -g 0_strange_calc.asm ld -melf_i386 -e main -dynamic-linker /lib/ld-linux.so.2 -o 0_strange_calc 0_strange_calc.o -lc
您可以使用GCC将目标文件链接到可执行文件,从而简化与C库的链接.要构建32位可执行文件,您可以使用:
nasm -f elf -g 0_strange_calc.asm gcc -m32 0_strange_calc.o -o 0_strange_calc
该Ç库和运行时刻有一个_start,做方法Ç启动初始化并依次调用一个调用的函数主要恰巧是在你的汇编文件的功能.-m32
告诉GCC你也链接到32位可执行文件.
您可能还需要安装gl的Multlilib版本(如果需要,还可以安装g ++),以便您可以使用适当的C库在64位Debian上正确构建和运行32位应用程序.这可以使用此命令行完成:
apt-get install gcc-multilib g++-multilib
在基于Ubuntu的系统上,您需要使用:
sudo apt-get install gcc-multilib g++-multilib