assembly GNU i386-汇编程序:i386/ Boot .S:错误:表达式后有'GDT 39'垃圾

nhaq1z21  于 2022-11-13  发布在  其他
关注(0)|答案(1)|浏览(129)

我试着按照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

我真的不能解释这些是什么意思。如果你需要任何进一步的信息,就问吧。
谢谢你的帮助!

7xllpg7q

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产生错误:

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'

1b是对标签1:的反向引用(前一行中的最近示例)。'a'的ASCII码是97,所以不知何故,它的ab部分说服了GAS将其视为$97b,而忘记了单引号。44','的ASCII码。

您的错误就是GAS在需要整数常量表达式的上下文中(如在$后面作为立即数),将多个非'字符作为单引号时产生的无意义错误。
39(十进制)是'单引号的ASCII代码。

像NASM这样的更好的汇编器可以让你执行mov eax, 'abcd'来得到EAX = 0x 64636261,准备存储到内存中,以便按照源代码的顺序得到这些ASCII字节。

相关问题