GNU i386汇编器GDT代码转换报错,求排查解决
GAS汇编转换GDT代码时的编译错误修复
背景
我正在学习OSDev的GDT设置教程,将NASM语法的示例代码手动转换为GAS语法(工具intel2gas无法处理部分代码),使用GNU-i386交叉编译器。以下是我的boot.S代码:
# 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
编译错误
编译时出现以下错误:
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
错误原因
错误中的GDT39是因为代码中用双引号''GDT''包裹符号名导致的:GAS汇编中不需要用引号引用符号,双引号会被解析为字符串,而39是单引号(ASCII 0x27)的十进制值,最终造成汇编器解析混乱。
另外原代码中movl [gdtr + 2], %eax逻辑错误,这是读取gdtr+2地址的值到%eax,但实际需求是把计算出的GDT物理地址写入gdtr的长字部分(即gdtr+2的位置)。
修复后的setGdt代码
修改两处问题:去掉符号名的双引号,修正寄存器和内存的读写方向:
gdtr: .word 0 .long 0 setGdt: xorl %eax,%eax movw %ds,%ax shll $4,%eax addl $GDT, %eax # 移除双引号,直接引用符号 movl %eax, [gdtr + 2] # 将GDT物理地址写入gdtr的长字部分 movl $GDT_end, %eax # 移除双引号 subl $GDT, %eax # 移除双引号 movw %ax, gdtr lgdt [gdtr] ret
额外注意事项
- 确保你已经在代码中定义了
GDT和GDT_end符号(比如在.rodata段中定义GDT表结构),否则会出现未定义符号的编译错误; - GAS中引用符号、标签时直接写名称即可,不需要添加引号或其他包裹符。
内容的提问来源于stack exchange,提问作者Wutpups
相关产品推荐
相关产品推荐

