如何将此 ATS 语法汇编代码转换为 NASM 语法,以便 NASM 可以理解:
.file "kernel.c"
.globl _videoMemory
.data
.align 4
_videoMemory:
.long 753664
.globl _screenWidth
.section .rdata,"dr"
.align 4
_screenWidth:
.long 80
.globl _screenHeight
.align 4
_screenHeight:
.long 25
.text
.globl _cls
.def _cls; .scl 2; .type 32; .endef
_cls:
LFB0:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
subl $16, %esp
movl $0, -4(%ebp)
jmp L2
L3:
movl _videoMemory, %edx
movl -4(%ebp), %eax
addl %edx, %eax
movb $32, (%eax)
movl _videoMemory, %eax
movl -4(%ebp), %edx
addl $1, %edx
addl %edx, %eax
movb $7, (%eax)
addl $2, -4(%ebp)
L2:
movl $80, %edx
movl $25, %eax
imull %edx, %eax
addl %eax, %eax
cmpl -4(%ebp), %eax
jg L3
nop
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE0:
.globl _strlen
.def _strlen; .scl 2; .type 32; .endef
_strlen:
LFB1:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
subl $16, %esp
movl $0, -4(%ebp)
jmp L5
L6:
addl $1, -4(%ebp)
addl $1, 8(%ebp)
L5:
movl 8(%ebp), %eax
movzbl (%eax), %eax
testb %al, %al
jne L6
movl -4(%ebp), %eax
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE1:
.globl _printchar
.def _printchar; .scl 2; .type 32; .endef
_printchar:
LFB2:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
subl $4, %esp
movl 8(%ebp), %eax
movb %al, -4(%ebp)
movl _videoMemory, %edx
movl 12(%ebp), %eax
addl %eax, %edx
movzbl -4(%ebp), %eax
movb %al, (%edx)
nop
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE2:
.globl _print
.def _print; .scl 2; .type 32; .endef
_print:
LFB3:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
subl $24, %esp
movl 8(%ebp), %eax
movl %eax, (%esp)
call _strlen
movl %eax, -8(%ebp)
movl $0, -4(%ebp)
jmp L10
L11:
movl -4(%ebp), %eax
addl %eax, %eax
movl %eax, %ecx
movl 8(%ebp), %edx
movl -4(%ebp), %eax
addl %edx, %eax
movzbl (%eax), %eax
movsbl %al, %eax
movl %ecx, 4(%esp)
movl %eax, (%esp)
call _printchar
addl $1, -4(%ebp)
L10:
movl -4(%ebp), %eax
cmpl -8(%ebp), %eax
jb L11
nop
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE3:
.section .rdata,"dr"
LC0:
.ascii "a\0"
.text
.globl _kmain
.def _kmain; .scl 2; .type 32; .endef
_kmain:
LFB4:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
subl $8, %esp
call _cls
movl $LC0, %eax
movsbl %al, %eax
movl $1, 4(%esp)
movl %eax, (%esp)
call _printchar
nop
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE4:
.ident "GCC: (MinGW.org GCC-6.3.0-1) 6.3.0"
我已经搜索过,但还没有找到任何从 AT&T 语法到 NASM 语法的翻译器。 如果您可以帮助我翻译此代码或提供任何可以的软件或教程,我将很高兴知道。
在 AT&T 中,
%
表示寄存器。 NASM 简单地解决了这个问题,因此删除 %
。 AT&T 的立即值以 $
开头,而 NASM 可以计算出来,因此请删除 $
。
在 AT&T 中,顺序是
instruction source, destination
,而在 NASM 中是 instruction destination, source
,所以交换它们。
AT&T:
movl (%ecx),%eax
。
NASM:`mov eax,[ecx]
在 AT&T 中,
()
是内存操作数。在 NASM 中,[]
是内存操作数。
AT&T:%segreg:disp(base,index,scale) == disp + base + indexscale,如果不存在,scale 默认为 1。 NASM:segreg:[基础+索引比例+显示]
AT&T: subl -0x20(%ebx,%ecx,0x4),%eax NASM: 子 eax,[ebx+ecx*4h-20h]
AT&T 在指令上使用后缀来确定内存大小,而 NASM 在必要时在内存地址之前使用单词。
AT&T:8 位是“b”后缀,16 位是“w”后缀,32 位是“l”后缀,64 位是“q”后缀。 NASM:8位是
byte
,16位是word
,32位是dword
,64位是qword
。
在 AT&T 中,全局标签可以以字母字符或
_
开头。在 NASM 中,全局标签可以以字母数字字符和 _
开头。在 AT&T 中,本地标签以数字开头。在 NASM 中,本地标签以 .
开头。
在 AT&T 中,指令以
.
开头。在 NASM 中,用户定义的指令以 @
开头,原始指令位于 []
之间。
不要搜索“将 NASM 转换为 AT&T”,而是搜索“将 Intel 转换为 AT&T”。 NASM 使用 Intel 语法。
这应该足以帮助您入门。
有些人让 GCC 和 GAS 使用 Intel 语法进行汇编。不过,从我读到的来看,它不太可靠。
如果此信息有任何不准确,请告知我或进行编辑。
因为这个问题,我启动了一个 GitHub repository 来转换汇编语法。也许您有兴趣做出贡献。我们可以协商使用哪种语言。