Assembly 使用Lodsb或mov打印.ascii声明
我正在写这个引导程序,它只是在屏幕上打印一些东西。这是我到目前为止在大会上所做的:Assembly 使用Lodsb或mov打印.ascii声明,assembly,x86,gnu-assembler,Assembly,X86,Gnu Assembler,我正在写这个引导程序,它只是在屏幕上打印一些东西。这是我到目前为止在大会上所做的: .globl _start .code16 _start: movw $0x0003, %ax int $0x10 movb $0x0e, %ah movb $0x69, %al int $0x10 movw $_header, %bx movb %bl, %al int $0x10 _header: .ascii "W\
.globl _start
.code16
_start:
movw $0x0003, %ax
int $0x10
movb $0x0e, %ah
movb $0x69, %al
int $0x10
movw $_header, %bx
movb %bl, %al
int $0x10
_header: .ascii "W\0"
.org 0x1FE
.byte 0x55
.byte 0xAA
现在它打印ASCII 69(“i”),但我希望它也打印.ASCII
声明。现在我只将它设置为“W”
,这样我就可以在Objdump
中轻松找到它。我似乎无法获得该值(57)。我可以leal$\u头,%edx
等等,但是我似乎无法访问%edx
处的值
我尝试使用lodsb
,但我似乎无法理解。我将%di
设置为0x00,并使用leal%si将%si
设置为\u header
的地址,但是我的lodsb
后跟int 0x10
似乎没有打印任何内容。如果您有任何想法,我将不胜感激。这里:
movw $_header, %bx
movb %bl, %al
首先,movb%bl,%al
不是从内存中读取一个字节到al
,而是从bl
中读取一个字节。您要将其更改为:
movb (%bx), %al
要仅从\u头中取出一个字符
,您可以直接将该字符从内存加载到al
:
movb _header, %al
其次,也是最重要的一点,你似乎在做几个假设:
您的代码以cs
=0x7c0、ip
=0开始运行。它可以是cs
=0,ip
=0x7c00,但是您的代码期望ip
=0(我从代码中推断,汇编器开始使用隐式.org 0
来组装它)。您应该使代码适应第二个选项。您可以使用跳转指令将cs
和ip
重新加载到更合适的值,如下所示:jmp$0x7c0,$\u next
和下一行的相应标签:\u next:
您的代码以ds
=0x7c0开始运行ds
不能保证设置为您想要或需要的任何值。你必须自己初始化它
最后,在最后一个int$0x10
之后会发生什么
经过更正后,您的代码应该如下所示:
.globl _start
.code16
_start:
/* .org 0 is implied here! But the code may start with ip != 0. */
jmp $0x7c0,$_next
_next:
/* We have just ensured that cs=0x7c0,ip=$_next */
/* Let's now load data segment registers with proper values */
movw %cs, %ax
movw %ax, %ds
movw %ax, %es
movw $0x0003, %ax
int $0x10
movb $0x0e, %ah
movb $0x69, %al
int $0x10
movw $_header, %bx
movb (%bx), %al /* read into al a byte from memory at address from bx */
int $0x10
/* Halt execution, don't just execute whatever garbage is in memory */
/*after the end of the code. */
_halt:
hlt
jmp _halt
_header: .ascii "W\0"
.org 0x1FE
.byte 0x55
.byte 0xAA
我现在唯一能推荐的另外两件事是将bh
设置为0(),并查看DisassAssembly(尝试ndisam
:ndisam-b 16 bootssectorfile
),以查看在使用objdump
等进行所有操作后,地址/偏移量是否正确。