我试着按照www.example.com上关于GDT设置的教程来做wiki.osdev.org。我试着把示例代码从NASM转换成GAS语法,但是intel 2gas工具不能转换一些我自己尝试的代码行。我不得不说我对汇编程序了解不多。这是我从 Boot .S上得到的代码,我使用的是GNU-i386-Cross-Compiler:
# 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
我真的不能解释这些是什么意思。如果你需要任何进一步的信息,就问吧。
谢谢你的帮助!
1条答案
按热度按时间7xllpg7q1#
$''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
产生错误:1b
是对标签1:
的反向引用(前一行中的最近示例)。'a'
的ASCII码是97
,所以不知何故,它的ab
部分说服了GAS将其视为$97b
,而忘记了单引号。44
是','
的ASCII码。您的错误就是GAS在需要整数常量表达式的上下文中(如在
$
后面作为立即数),将多个非'
字符作为单引号时产生的无意义错误。39
(十进制)是'
单引号的ASCII代码。像NASM这样的更好的汇编器可以让你执行
mov eax, 'abcd'
来得到EAX = 0x 64636261,准备存储到内存中,以便按照源代码的顺序得到这些ASCII字节。