Linux 美国电话电报公司;T.试着;movb“;要注册的字符常量,核心转储
我用的是ubuntu64+汽油 我使用AT&T汇编,我试着给al寄存器分配一个“e”,并把它编译成32位程序 $cat c2.sLinux 美国电话电报公司;T.试着;movb“;要注册的字符常量,核心转储,linux,assembly,crash,att,mov,Linux,Assembly,Crash,Att,Mov,我用的是ubuntu64+汽油 我使用AT&T汇编,我试着给al寄存器分配一个“e”,并把它编译成32位程序 $cat c2.s .code32 .globl _start _start: movb 'e',%al # Problem here!!!! mov $1,%eax mov $0,%ebx int $0x80 $as-g c2.s-o c2.o&ld c2.o-o c2 c2美元 分段故障(SIGVEGV) 我用gdb调试c2,发现它在movb'e',%al处崩溃。太
.code32
.globl _start
_start:
movb 'e',%al # Problem here!!!!
mov $1,%eax
mov $0,%ebx
int $0x80
$as-g c2.s-o c2.o&ld c2.o-o c2
c2美元
分段故障(SIGVEGV)
我用gdb调试c2,发现它在movb'e',%al处崩溃。太奇怪了,“movb”怎么会崩溃
然后,我将语法切换为使用intel相同的内容:
$cat b2.s
.intel_syntax noprefix
.code32
.section .text
.global _start
_start:
mov al,'e'
mov eax,1
mov ebx,0
int 0x80
$as-g b2.s-o b2.o和&ld b2.o-o b2
b2美元
这次没问题。但是为什么,我对AT&T汇编的使用有什么问题吗?不是很有趣。AS为AT&T语法生成此目标代码
400078: a0 65 00 00 00 b8 01 movabs 0x1b800000065,%al
40007f: 00 00
400081: 00 bb 00 00 00 00 add %bh,0x0(%rbx)
400087: cd 80 int $0x80
显然,位置0x1B80000065未映射,而是Intel
400078: b0 65 mov $0x65,%al
40007a: b8 01 00 00 00 mov $0x1,%eax
40007f: bb 00 00 00 00 mov $0x0,%ebx
400084: cd 80 int $0x80
从AT&T中删除.code32,您将获得此信息
400078: 8a 04 25 65 00 00 00 mov 0x65,%al
40007f: b8 01 00 00 00 mov $0x1,%eax
400084: bb 00 00 00 00 mov $0x0,%ebx
400089: cd 80 int $0x80
注意它希望如何将内存位置0x64的内容移动到AL中
movb $'e',%al
解决了这个问题。在任何情况下,在64位系统上开发32位代码可能会让您在某个时候感到悲伤,特别是当您开始处理堆栈时。听起来很奇怪,您能否再次组装第一个示例,并使用
objdump-d file.o
查看实际的操作码?对第二种情况执行相同的操作,并进行比较。乍一看,它们和我一模一样。你不应该需要.code32
指令。将--32
传递给汇编程序,汇编32位代码.code32
仅更改汇编程序识别和汇编的内容,但不会使输出成为32位对象文件。