2012-03-07 30 views
3

在我努力理解如何使用GNU binutils構建一個簡單的引導裝載程序時使用了 gas我遇到過這個問題,你如何告訴鏈接器將數據放在哪裏,放在一個使用.org的文件中,以將文件大小保持在512字節的同時前進位置計數器。我似乎無法找到辦法做到這一點。在.data部分使用.org指令來處理數據:關於ld

,試圖做到這一點的彙編程序是:

# 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 使用以下命令我得到以下錯誤:

[email protected]:~/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' 
+0

生成此錯誤的最小示例及其含義:http://stackoverflow.com/a/32639540/895245具有工作引導扇區和BIOS示例的存儲庫:https://github.com/cirosantilli/x86-bare- metal-examples – 2015-09-17 20:49:10

回答

4

對於這方面的工作你應該寫你自己的linker script。只需將它傳遞給-T選項的鏈接器即可。

我對幾乎相同的問題腳本是:

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

的那套把戲你不活動需要把0x55 0xAA在彙編!

0x1000開頭:其實所有的跳躍是相對的,這樣就不會使用,但以後需要的跳轉進入保護模式...

endbootsecwendbootsecimage的符號在其他地方使用在代碼中。

+0

我得到:'a.ld:11無法使用Binutils 2.24上的鏈接器腳本向後移動位置計數器(從0000000000001200到00000000000011fe)。 – 2015-09-06 16:49:06

+0

」正在做我的鏈接器技巧和.org的東西在同一時間「DOH! – 2015-09-07 14:16:16