kakuyou 发表于 2003-6-20 15:39:45

怎么用ld来编译软盘启动的程序

http://www.linuxfans.org/nuke/modules.php?name=News&file=article&op=view&sid=614

这个例子大家看过没有,照着文中那么做是没有问题,我把它改成了AT&T格式的汇编。
原来的代码:
entry start
start:
      mov ax,#0xb800
      mov es,ax
      seg es
      mov ,#0x41
      seg es
      mov ,#0x1f
loop1: jmp loop1


我改的源代码如下:
.text
.code16

.global start
start:
        movw $0xb800, %ax
        movw %ax, %es
       
        movb $0x41, %es:0
        movb $0x1f, %es:1

loop1:       
        jmp loop1

编译方法:
as -a -o boot.o boot.s
连接方法:
ld -o boot -M -N -s --static boot.o

重启后却什么也没反应,我什么地方错了,那位高手给指正以下。

xdwjack 发表于 2003-6-20 16:41:23

你是不是完全按照那篇文章说的来做的?我按照那个方法来做,结果如下

# as86 boot.s -o boot.o
as: error reading input

# ld86 -d boot.o -o boot
ld86: premature end of input file boot.o

不知道为什么.

kakuyou 发表于 2003-6-20 16:55:12

应该是
as86 -o boot.o boot.s

ld86 -d -o boot boot.o


源在后,结果在前

xdwjack 发表于 2003-6-20 17:02:01

还是同样的提示,你是否可以把你的命令执行情况贴出来?
我是把那几个程序copy过来保存的.

还有就是那个c程序前面的3个include语句后面都没有文件名,是为什么

kakuyou 发表于 2003-6-20 17:14:19

啊,刚才对不起
在前在后都一样,我一般是把源放在后头
那些命令肯定是没有错的,可能你copy的时候带进了什么东西(例如汉字的空格),
反正程序很短,你还是从输一遍吧

那几个include是让你自己加的,可能是有的系统上放在不同的位置上了
我的write.c程序

#include <stdio.h>
#include <memory.h>
#include <unistd.h>
#include &lt;fcntl.h&gt;

int main()
{
      char boot_buf;
      int floppy_desc, file_desc;

      memset (boot_buf,0x00,sizeof boot_buf);

      file_desc = open ("./boot",O_RDONLY);
      if (-1 == file_desc)
      {
                printf ("Open ./boot failed! \n");
                return -1;
      }
      read (file_desc, boot_buf, 510);
      close (file_desc);
      boot_buf = 0x55;
      boot_buf = 0xaa;
      floppy_desc = open ("/dev/fd0", O_RDWR);
      if (-1 == floppy_desc)
      {
                printf ("Open /dev/fd0 failed !\n");
                return -1;
      }
      lseek (floppy_desc, 0, SEEK_CUR);
      write (floppy_desc, boot_buf, 512);
      close (floppy_desc);

      return (0);
}

kakuyou 发表于 2003-6-20 17:17:03

奇怪了

第三个空的include是
#include &lt;unistd.h&gt;

kakuyou 发表于 2003-6-20 17:19:26

是不是论坛禁止了
再贴

unistd.h

xdwjack 发表于 2003-6-20 17:45:08

我敲入了你的汇编代码,结果如下:
# cat boot.s
.text
.code16

.global start
start:
movw $0xb800,%ax
movw %ax,%es

movb $0x41,%es:0
movb $0x1f,%es:1

loop1:
jmp loop1

xdwjack 发表于 2003-6-20 17:46:13

# as -a -o boot.o boot.s
GAS LISTING boot.s                      page 1


   1                  .text
   2                  .code16
   3
   4                  .global start
   5                  start:
   6 0000 B800B8      movw $0xb800,%ax
   7 0003 8EC0          movw %ax,%es
   8
   9 0005 26C60600      movb $0x41,%es:0
   9      0041
10 000b 26C60601      movb $0x1f,%es:1
10      001F
11
12                  loop1:
13 0011 EBFE          jmp loop1
14
GAS LISTING boot.s                     page 2


DEFINED SYMBOLS
            boot.s:5      .text:00000000 start
            boot.s:12   .text:00000011 loop1

NO UNDEFINED SYMBOLS

这样正常吗?

kakuyou 发表于 2003-6-20 18:05:04

编译到是没错...

我前面已经说过了,我的程序运行不了...

Dragonfly 发表于 2003-6-20 21:48:58

奇怪了

第三个空的include是
#include &lt;unistd.h&gt;



use

kakuyou 发表于 2003-6-20 23:54:15

不知道什么地方错了,反正我的ie里第三个就是空的

kakuyou 发表于 2003-6-22 00:15:07

昨天调出来了,如果有人有兴趣,可以自己试试
编译指令
as -a -o boot.o boot.s
链接指令
ld -nostdlib -static -N -e start -Ttext 0x7c00 -o boot.out boot.o
最后的生成指令
objcopy -S -O binary boot boot.out

不知道为什么,linux的i386部分汇编代码最近才改成完全使用at&t汇编,还要使用非gnu的工具,我是参考了FreeBSD的Make文件才弄好的,FreeBSD到是从头尾使用gnu的工具制作,也许还是FreeBSD的态度更严肃专业吧。。。

xdwjack 发表于 2003-6-22 11:59:01

是否可以把你上面的指令的含义和采用各个参数的理由讲一下,我想这可以让我们更加明白内部的机理。最好还可以把你修改过的汇编程序讲解一下,每个指令和标志都是干什么用的,AT&T汇编和Intel汇编的风格方面有什么不同的地方,为什么你把Intel汇编修改之后就应该是那个样子,等等。还有你开始的时候没有弄好,原因在什么地方等等,而且最好多叙述一些原理性的东西。谢谢,我想通过你的总结,也可以让兄弟们对汇编和操作系统的原理有更深刻的认识,毕竟这方面的东西还是很少的,实际的应用的例子就更是少了。谢谢!

Dragonfly 发表于 2003-6-22 23:19:45

yes, kakuyou, pls summarize it if u have time. and this summary can let u rethink old and learn new again.:-D:-D:-D
页: [1] 2
查看完整版本: 怎么用ld来编译软盘启动的程序