GNU i386-汇编程序:arch/i386/boot。S:错误:表达式后出现垃圾"GDT39"



我尝试遵循wiki.osdev.org中关于GDT设置的教程。我试图将示例代码从NASM转换为GAS语法,但工具intel2gas无法转换一些行,然后我自己尝试了。我不得不说,我对汇编程序了解不多。这是我启动时的代码。S和我正在使用GNU-i386交叉编译器:

# Declare constants for the multiboot header.
.set ALIGN,    1<<0             # align loaded modules on page boundaries
.set MEMINFO,  1<<1             # provide memory map
.set FLAGS,    ALIGN | MEMINFO  # this is the Multiboot 'flag' field
.set MAGIC,    0x1BADB002       # 'magic number' lets bootloader find the header
.set CHECKSUM, -(MAGIC + FLAGS) # checksum of above, to prove we are multiboot
.section .rodata

# Declare a header as in the Multiboot Standard.
.section .multiboot
.align 4
.long MAGIC
.long FLAGS
.long CHECKSUM
# Reserve a stack for the initial thread.
.section .bss
.align 16
stack_bottom:
.skip 16384 # 16 KiB
stack_top:
# The kernel entry point.
.section .text
.global _start
.type _start, @function
_start:
movl $stack_top, %esp
# Call the global constructors.
call _init
# Transfer control to the main kernel.
call kernel_main
# Hang if kernel_main unexpectedly returns.
cli
1:  hlt
jmp 1b
.size _start, . - _start
gdtr:   .word 0
.long 0
setGdt:
xorl %eax,%eax
movw %ds,%ax
shll $4,%eax
addl $''GDT'', %eax
movl [gdtr + 2], %eax
movl $''GDT_end'', %eax
subl $''GDT'', %eax
movw %ax, gdtr
lgdt [gdtr]
ret

这也是OSDev.org上Meaty Skeleton文章中描述的几乎相同的文件。

我的错误是:

arch/i386/boot.S: Assembler messages:
arch/i386/boot.S:51: Error: junk `GDT39' after expression
arch/i386/boot.S:53: Error: junk `GDT_end39' after expression
arch/i386/boot.S:54: Error: junk `GDT39' after expression

我真的无法解释这些是什么意思。如果您需要任何进一步的信息,请询问。

谢谢你的帮助!

$''GDT''和类似表达式中的单引号不是有效的GAS语法。不要这样做,只需使用mov $GDT_end, %eax/sub $GDT, %eax即可。

或者更好的是,在组装时用mov $GDT_end - GDT, %eax计算这个常数


GAS可能会被这些窒息,或者因为它以'开头,所以将整个事情视为一个字符文字。但是GAS在解析'之后有多个字符的字符文本时却一团糟。

我认为它的解析代码非常简单和粗糙,
因为mov $'a, %eax(无结束引号(与mov $'a', %eax组装相同

mov $'abcd', %eax产生错误:

foo.s:1: Error: backward ref to unknown label "97:"
foo.s:1: Error: junk `cd44%eax' after expression
foo.s:1: Error: number of operands mismatch for `mov'

CCD_ 10将是对标签CCD_ 11(前一行上的最新实例(的向后引用。'a'的ASCII代码是97,所以不知何故,它的ab部分说服GAS将其视为$97b,忘记了单引号。CCD_ 16是CCD_ 17的ASCII码。

当GAS需要一个整数常量表达式(如在$之后作为立即数(的上下文中有多个非'字符作为单引号时,您的错误就是GAS产生的那种无意义的错误。

39(十进制(是'单引号的ASCII代码

像NASM这样的更好的汇编程序允许您执行mov eax, 'abcd'以获得EAX=0x64636261,并准备好存储到内存中以按源顺序获得这些ASCII字节。但GAS并没有这么做,它的解析器甚至没有考虑任何人会尝试的可能性。

最新更新