mov指令后缀无效报错?内核内联汇编打印字符A问题求助
Let's dig into why you're getting that assembler error and fix it step by step. Your code has two main issues: mixing AT&T and Intel syntax, plus a small quirk with how the GNU assembler (GAS) handles segment registers in 32-bit Intel mode.
1. Fix the mov ds, ax instruction
The "invalid instruction suffix for mov'" error on this line happens because in 32-bit Intel mode, GAS can't automatically infer the operand size when moving to a segment register (which is 16-bit). You need to explicitly mark it as a 16-bit operation with the word` keyword:
mov word ds, ax
2. Fix the movb 0,'A' instruction
Here you're using AT&T syntax conventions (the movb suffix + source-first operand order) but told GCC to use Intel syntax with -masm=intel. In Intel syntax:
- We don't use suffixes like
movb; instead, we usebyte ptrto specify a byte-sized memory operation. - The operand order is destination first, source second.
Rewrite that line to match Intel syntax:
mov byte ptr [0], 'A'
This tells the assembler to write the byte value 'A' to memory offset 0 relative to the ds segment (which we set to 0xb800, so the physical address is 0xb8000—the start of text-mode video memory).
Full corrected code
Putting it all together, your print function should look like this:
void print(){ asm volatile( "mov ax, 0xb800\n" "mov word ds, ax\n" "mov byte ptr [0], 'A'\n" ); }
Quick runtime correctness note
If you're compiling with -m32, you're targeting 32-bit protected mode. Loading ds directly with 0xb800 won't work here—segment registers hold selectors (not raw base addresses) in protected mode. If you're writing a real-mode kernel, you should compile for 16-bit instead (use -m16 with GCC, though note 16-bit support is limited in modern versions). For protected mode, you'll need to set up a GDT entry for the video memory segment first, then load the corresponding selector into ds.
内容的提问来源于stack exchange,提问作者Clement Poon

