non-32bit-relocation

Terry Lambert tlambert2 at mindspring.com
Sat Jun 28 00:39:51 PDT 2003


Andrew wrote:
> I wrote a small assembly program to send a string to the floppy.
> I'm not familiar with nasm, the assembly language compiler I'm using and
> even less familiar with the as program.
> 
> basically, other code aside, the nasm compiler says, when using -f elf, that
> it does not support non-32-bit relocations.  Ok, I'm not an assembly expert
> and less familiar with 'elf' so I need some help.

There are a number of assembly language resources for FreeBSD; here
are a couple of the better ones:

	http://www.int80h.org/bsdasm/
	http://linuxassembly.org/resources.html


> The instructions were
> 
> mov es, seg buffer
> mov bx, [buffer]
> int 13h.
> 
> Can anyone tell me how to do this on a FreeBSD machine?

You either don't do this at all, or you use the vm86() system
call to do the work in a virtual machine.  In general, this
will not work for this particular use, since INT 0x13 is used
to do disk I/O, and the BIOS interface does not own the disk,
the OS disk driver does.

To do what you want to do, you should probably call the open(2)
system call on the disk device from assembly, and then call the
write(2) system call from assembly, instead of trying to use
INT 0x13.

Here's a little program to write some garbage to /dev/fd0; I call
it "foo.s".  Don't run it against a floppy you care about.  Compile
it with "cc -o foo foo.s"; it will create a dynamically linked
program, unless you tell it not to (e.g. "cc -static -o foo foo.s".

If you don't want crt0 involved so that you can mix C and assembly,
then you should follow the link above to the first tutorial.

Here's the code:

----------------------------------------------------------------
        #
        #       Assembly program to write a string to the floppy
        #

        #
        # Here are my strings
        #
        .section        .rodata

# "/dev/fd0" + NUL
.device_to_open:
        .byte    0x2f,0x64,0x65,0x76,0x2f,0x66,0x64,0x30,0x0

# "my string"
.string_to_write:
        .byte    0x6d,0x79,0x20,0x73,0x74,0x72,0x69,0x6e,0x67



      #
      # Code goes in text section
      #
.text
      .p2align 2,0x90

      # "main()" -- called by crt0's _main() function
.globl main
        .type            main, at function
main:
      pushl %ebp                # main is a function; this is the
      movl %esp,%ebp            # entry preamble for a function with
      subl $8,%esp              # no parameters
      addl $-4,%esp             #

      # fd = open(char *path, int flags, int mode)
      pushl $0          # mode 0 (not used; callee might care though)
      pushl $2          # flags; 2 = O_RDWR
      pushl $.device_to_open    # path string; must be NUL terminated
      call open         # call open function
      addl $16,%esp
      movl %eax,%eax
      movl %eax,fd              # system call return is in %eax (-1 == error)
      addl $-4,%esp

      # write(int fd, char *buf, int len)
      pushl $9          # len = 9 bytes
      pushl $.string_to_write   # buf; does not need NUL termination
      movl fd,%eax              # fd
      pushl %eax
      call write                # call write function
      addl $16,%esp
      addl $-12,%esp

      # close(fd)
      movl fd,%eax              # fd
      pushl %eax
      call close                # call close function
      addl $16,%esp

      # just return... we could have called exit, but _main will do that
      leave
      ret
.finish:
        .size            main,.finish-main      # text segment size

      .comm     fd,4,4          # global variable 'fd'

      #
      # done.
      #
----------------------------------------------------------------

-- Terry


More information about the freebsd-hackers mailing list