3

GNU binutilsを使用して、ガスを使用して単純なブートローダーを構築する方法を理解するための努力の 中で、.orgを使用してロケーションカウンターを進めるファイルで、データを配置する場所をリンカーにどのように指示するかという質問に遭遇しました。ファイルサイズを512バイトに保ちながら。私はこれを行う方法を見つけることができないようです。

これを行おうとするアセンブリプログラムは次のとおりです。

# Author: Matthew Hoggan
# Date Created: Tuesday, Mar 6, 2012

.code16                      # Tell assembler to work in 16 bit mode
.section .data
msg:                         # Message to be printed to the screen
  .asciz "hello, world"

.section .text
.globl _start                # Help linker find start of program
_start:
  xor  %ax,  %ax             # Zero out ax register (ah used to specify bios function to Video Services) 
  movw %ax,  %ds             # Since ax is 0x00 0x00 use it to set data segment to 0
  mov  $msg, %si             # Use source index as pointer to string

loop:
  movb %ds:(%si), %al        # Pass data to BIOS function in low nibble of ax
  inc  %si                   # Advance the pointer
  or   %al, %al              # If byte stored in al is equal to zero then...
  jz   _hang                 # Zero signifies end of string
  call print_char            # Print current char in al
  jmp loop                   # Repeat

#
# Function that uses bios function calls
# to print char to screen
#
print_char:
  movb $0x0e, %ah             # Function to print a character to the screen
  movb $0x07, %bl             # color/style to use for the character
  int  $0x10                  # Video Service Request to Bios
  ret

#
# Function used as infinite loop
#
_hang:
  jmp  _hang

.org 510
.byte 0x55, 0xAA

.end

UPDATE 次のコマンドを使用すると、次のエラーが発生します。

mehoggan@mehoggan-laptop:~/Code/svn_scripts/assembly/bootloader/gas$ ld --oformat binary -o string string.o 
string.o: In function `_start':
(.text+0x5): relocation truncated to fit: R_X86_64_16 against `.data'
4

1 に答える 1

4

この種の作業では、独自のリンカースクリプトを作成する必要があります。-Tオプションを指定してリンカーに渡すだけです。

ほぼ同じ問題に対する私のスクリプトは次のとおりです。

SECTIONS
{
    . = 0x1000;
    bootsec :
    {
        *(.text)
        *(.data)
        *(.rodata)
        *(.bss)
        endbootsec = .;
        . = 0x1FE;
        SHORT(0xAA55)
    }
    endbootsecw = endbootsec / 2;
    image = 0x1200;
}

0x55 0xAAそのトリックを使えば、イベントをアセンブラに入れる必要はありません!

0x1000冒頭:実際にはすべてのジャンプは相対的であるため、使用されませんが、後でプロテクトモードにジャンプするために必要になります...

endbootsecwendbootsecおよびimageは、コードの他の場所で使用される記号です。

于 2012-03-07T15:31:42.090 に答える