这两个汇编代码段有什么区别?

时间:2011-09-14 14:49:07

标签: assembly x86

我正在学习使用工具“as”和“ld”为X86机器编写启动加载程序,但我遇到了一个问题。

makefile如下:

AS=as
LD=ld

.s.o:
        ${AS} -a $< -o $*.o >$*.map

all: final.img

final.img: bootsect
        mv bootsect final.img

bootsect: bootsect.o
        ${LD} --oformat binary -N -e start -Ttext 0x7c00 -o bootsect $<

clean:
    rm -rf *.o *.map *.img

当我在下面创建bootsect.s文件来构建final.img时,没有问题,屏幕上显示“Hello world”

    .text
    .globl start
    .code16
start:
    jmp code
msg:
    .string "Hello world!\x0"
code:
    movw $0xb800, %ax
    movw %ax, %es #for display buffer address
        movw $0, %ax
    movw %ax, %ds   
    movw $msg, %si
    movw $0, %di
    cld
    movb $0x07, %al
1:
    cmp $0, (%si)
    je 1f
    movsb #DS:(E)SI to ES:(E)DI
    stosb #AL to ES:(E)DI
    jmp 1b
1:      jmp 1b
.org 0x1fe, 0x90
.word 0xaa55

但如果我对bootsect.s进行了一些改动,如下所示:

    .text
    .globl start
    .code16
msg:
    .string "Hello world!\x0"
start:
    movw $0xb800, %ax
    movw %ax, %es #for display buffer address
    movw $0, %ax
    movw %ax, %ds   
    movw $msg, %si
    movw $0, %di
    cld
    movb $0x07, %al
1:
    cmp $0, (%si)
    je 1f
    movsb #DS:(E)SI to ES:(E)DI
    stosb #AL to ES:(E)DI
    jmp 1b
1:      jmp 1b
.org 0x1fe, 0x90
.word 0xaa55

屏幕上没有任何输出。

我很困惑为什么?你能帮帮我吗?

感谢。

1 个答案:

答案 0 :(得分:4)

当你输出一个二进制文件时,你指定的入口点对程序的运行没有任何影响,因为没有标题来指定它。加载器只是从一个特定的偏移开始,这与引导加载程序是一个开始文件。当您将字符串作为程序集中的第一个内容时,它也将是输出中的第一个内容,这意味着处理器会将其视为代码并尝试执行它。如果幸运的话,该字符串将快速生成无效的操作码,允许您确定发生了什么。如果你运气不好,字符串将是有效的代码,程序将“运行”,但结果将不是你所期望的。