Assembly 为什么称呼错了?在x86实模式下启动扇区代码

Assembly 为什么称呼错了?在x86实模式下启动扇区代码,assembly,Assembly,使用GAS AT&T assembly在x86实模式下尝试将两个字母“UV”写入引导扇区中的视频内存(0xb8000)时,将“UV”打印在屏幕中心附近的某个位置,而“UV”应打印在屏幕的左上方 使用的命令: as os1.s -o os1.o;ld os1.o -o os1 -Ttext=0x7c00 --oformat=binary;sudo qemu-system-x86_64 -cpu max -drive format=raw,file=os1 “UV”应该在屏幕的最开始处打印,而不是在

使用GAS AT&T assembly在x86实模式下尝试将两个字母“UV”写入引导扇区中的视频内存(0xb8000)时,将“UV”打印在屏幕中心附近的某个位置,而“UV”应打印在屏幕的左上方

使用的命令:

as os1.s -o os1.o;ld os1.o -o os1 -Ttext=0x7c00 --oformat=binary;sudo qemu-system-x86_64 -cpu max -drive format=raw,file=os1
“UV”应该在屏幕的最开始处打印,而不是在屏幕中央的某个位置。

更改%ds后,从scn_pos读取的内存将使用新ds执行,因此它将读取其他一些内存位置。您可以使用%cs:scn\u pos。更好的选择可能是使用%es来寻址屏幕,并且不更改%ds。@prl:如果没有设置cs,使用%cs:scn\u pos也会有自己的问题。除非执行某种类型的farjmp(ljmp)来设置它,否则不能依赖CS为0x0000。我只想使用ES@Michael,我想到了这一点,但出于某种原因,我认为调用write_screen已经依赖于CS的值。显然不是。。。所以,杰西,忽略我的第一个建议,用ES在屏幕上讲话。嗨,prl,Michael,还有大家。谢谢。在使用%es而不是%ds后,程序现在可以正常工作。我将继续探索更多^-^。更改%ds后,将使用新的ds执行从scn_pos读取的内存,因此它将读取其他一些内存位置。您可以使用%cs:scn\u pos。更好的选择可能是使用%es来寻址屏幕,并且不更改%ds。@prl:如果没有设置cs,使用%cs:scn\u pos也会有自己的问题。除非执行某种类型的farjmp(ljmp)来设置它,否则不能依赖CS为0x0000。我只想使用ES@Michael,我想到了这一点,但出于某种原因,我认为调用write_screen已经依赖于CS的值。显然不是。。。所以,杰西,忽略我的第一个建议,用ES在屏幕上讲话。嗨,prl,Michael,还有大家。谢谢。在使用%es而不是%ds后,程序现在可以正常工作。我将继续探索更多^-^。

.code16          #! tells the assembler to generate 16-bit code
.globl _start
                    #.section .data
.section .text
_start:
movw $0x0d55, %ax
call write_screen
movw $0x0d56, %ax
call write_screen
jmp .
write_screen:
    push %ds
    pushl %ebx
    mov $0xb800, %bx  #! 0xb800 changes to scn_sel at 32-bit mode
    mov %bx,%ds
    mov scn_pos, %bx
    mov %ax, (%bx) # write to screen
    add $2, %bx
    cmp $2000, %bx
    jb 1f
    mov $0, %bx
1:  mov %bx, scn_pos
    popl %ebx
    pop %ds
    ret
scn_pos:
    .word 0x0    #! needs to be 32-bit at 32-bit mode
.org 510
.word 0xAA55