在64位Linux和64位处理器上运行32位汇编代码:解释异常
我在一个有趣的问题.我忘了我使用64位机器&操作系统并写了一个32位汇编代码.我不知道如何写64位代码.
这是Linux上Gnu Assembler(AT& T语法)的x86 32位汇编代码. //hello.S #include <asm/unistd.h> #include <syscall.h> #define STDOUT 1 .data hellostr: .ascii "hello wolrdn"; helloend: .text .globl _start _start: movl $(SYS_write),%eax //ssize_t write(int fd,const void *buf,size_t count); movl $(STDOUT),%ebx movl $hellostr,%ecx movl $(helloend-hellostr),%edx int $0x80 movl $(SYS_exit),%eax //void _exit(int status); xorl %ebx,%ebx int $0x80 ret 现在,这个代码应该在32位处理器上运行良好32位操作系统?我们知道64位处理器向后兼容32位处理器.所以,这也不会是一个问题.出现这个问题是因为系统调用和呼叫机制在64位操作系统32位操作系统.我不知道为什么,但是他们改变了32位linux& 64位linux. asm / unistd_32.h定义: #define __NR_write 4 #define __NR_exit 1 asm / unistd_64.h定义: #define __NR_write 1 #define __NR_exit 60 无论如何,使用宏而不是直接数字是有偿的.确保正确的系统呼叫号码. 当我组装&链接&运行程序. $cpp hello.S hello.s //pre-processor $as hello.s -o hello.o //assemble $ld hello.o // linker : converting relocatable to executable 它不打印helloworld. 在gdb中显示: >程序退出代码01. 我不知道如何在gdb中进行调试.使用教程我试图调试它,并在每个步骤执行指令检查寄存器的指令.它总是显示“程序退出01”.如果有的话可以告诉我如何调试这将是很棒的. (gdb) break _start Note: breakpoint -10 also set at pc 0x4000b0. Breakpoint 8 at 0x4000b0 (gdb) start Function "main" not defined. Make breakpoint pending on future shared library load? (y or [n]) y Temporary breakpoint 9 (main) pending. Starting program: /home/claws/helloworld Program exited with code 01. (gdb) info breakpoints Num Type Disp Enb Address What 8 breakpoint keep y 0x00000000004000b0 <_start> 9 breakpoint del y <PENDING> main 我试过运行strace.这是它的输出: execve("./helloworld",["./helloworld"],[/* 39 vars */]) = 0 write(0,NULL,12 <unfinished ... exit status 1> >在strace的输出中解释write(0,12)系统调用的参数? 编辑: 阅读保罗·R的答案后.我检查了我的文件 claws@claws-desktop:~$file ./hello.o ./hello.o: ELF 64-bit LSB relocatable,x86-64,version 1 (SYSV),not stripped claws@claws-desktop:~$file ./hello ./hello: ELF 64-bit LSB executable,statically linked,not stripped 我同意他的看法,这些应该是ELF 32位可重定位&可执行文件.但这并不能解答我的问题.我的所有问题仍然存在疑问.在这种情况下究竟发生了什么?有人可以回答我的问题并提供这个代码的x86-64版本吗? 解决方法
请记住,默认情况下,64位操作系统上的所有内容都倾向于假定为64位.您需要确保(a)在适当的情况下使用32位版本的#includes(b)与32位库链接,(c)构建32位可执行文件.如果您显示您的makefile的内容(如果您有),或者您正在使用的命令来构建此示例,则可能会有所帮助.
FWIW我改变了你的代码(_start – > main): #include <asm/unistd.h> #include <syscall.h> #define STDOUT 1 .data hellostr: .ascii "hello wolrdn" ; helloend: .text .globl main main: movl $(SYS_write),%ebx int $0x80 ret 并建立如下: $gcc -Wall test.S -m32 -o test 我们有一个32位可执行文件: $file test test: ELF 32-bit LSB executable,Intel 80386,for GNU/Linux 2.6.4,dynamically linked (uses shared libs),not stripped 它似乎运行正常: $./test hello wolrd (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 默认的ulimit值设置在哪里? (linux,centos)
- 如何在Linux(特别是Fedora 9)上使我的默认(或任何静态)路由
- 第一章安装Linux,RPM、YUM, systemctl
- 禁用Linux上的Apache自动启动
- 在Ubuntu Linux GEOS / GDAL问题上安装功能齐全的PostGIS 2
- SElinux:如何在不重启的情况下更改为许可模式?
- osx – 如果不支持-i参数,如何使用grep和sed替换多个文件中
- OpenSolaris和Linux之间的主要实际区别是什么?
- 【推荐】Redhat 5配置YUM服务器【利用DVD盘做yum源】
- linux – 停止Tomcat后SSH没有响应,许多ksoftirqd CPU使用率