【问题标题】:ORG alternative for C++C++ 的 ORG 替代品
【发布时间】:2013-09-02 19:59:51
【问题描述】:

在汇编中,我们使用org 指令将位置计数器设置为内存中的特定位置。这对于制作操作系统特别有用。这是一个示例引导加载程序(来自 wikibooks):

 org 7C00h

         jmp short Start ;Jump over the data (the 'short' keyword makes the jmp instruction smaller)

 Msg:    db "Hello World! "
 EndMsg:

 Start:  mov bx, 000Fh   ;Page 0, colour attribute 15 (white) for the int 10 calls below
         mov cx, 1       ;We will want to write 1 character
         xor dx, dx      ;Start at top left corner
         mov ds, dx      ;Ensure ds = 0 (to let us load the message)
         cld             ;Ensure direction flag is cleared (for LODSB)

 Print:  mov si, Msg     ;Loads the address of the first byte of the message, 7C02h in this case

                         ;PC BIOS Interrupt 10 Subfunction 2 - Set cursor position
                         ;AH = 2
 Char:   mov ah, 2       ;BH = page, DH = row, DL = column
         int 10h
         lodsb           ;Load a byte of the message into AL.
                         ;Remember that DS is 0 and SI holds the
                         ;offset of one of the bytes of the message.

                         ;PC BIOS Interrupt 10 Subfunction 9 - Write character and colour
                         ;AH = 9
         mov ah, 9       ;BH = page, AL = character, BL = attribute, CX = character count
         int 10h

         inc dl          ;Advance cursor

         cmp dl, 80      ;Wrap around edge of screen if necessary
         jne Skip
         xor dl, dl
         inc dh

         cmp dh, 25      ;Wrap around bottom of screen if necessary
         jne Skip
         xor dh, dh

 Skip:   cmp si, EndMsg  ;If we're not at end of message,
         jne Char        ;continue loading characters
         jmp Print       ;otherwise restart from the beginning of the message


 times 0200h - 2 - ($ - $$)  db 0    ;Zerofill up to 510 bytes

         dw 0AA55h       ;Boot Sector signature

 ;OPTIONAL:
 ;To zerofill up to the size of a standard 1.44MB, 3.5" floppy disk
 ;times 1474560 - ($ - $$) db 0

是否可以用 C++ 完成任务?是否有任何命令、函数等,例如org,我可以在其中更改程序的位置?

【问题讨论】:

    标签: c++ memory assembly operating-system ram


    【解决方案1】:

    不,在我所知道的任何 C 编译器中都不可能这样做。但是,您可以创建自己的linker script,将代码/数据/bss 段放置在特定地址。

    【讨论】:

    • 所以你的意思是,我必须为引导加载程序使用汇编,并且不可能使用任何其他语言?
    • @AnshumanDwibhashi 不,您仍然可以使用链接描述文件来设置地址。但是,对于第一步引导加载程序,通常更容易在汇编程序中编写它,然后调用适当的更高级别代码。
    • 好的,谢谢@JoachimPileborg,但你能提供一些示例代码吗?
    • @AnshumanDwibhashi 不是用于 C 中的一级引导加载程序。我从未用 C 制作过,也从未见过,但它绝对是可能的。
    • no... @JoachinPileborg 我不是指引导加载程序的示例,我指的是使用您规定的方法移动内存的示例
    【解决方案2】:

    为了清楚起见,org 指令不会在指定地址加载代码,它只是通知汇编程序代码将在该地址加载。显示的代码似乎是针对 Nasm(或类似)的 - 在 AT&T 语法中,.org 指令做了一些不同的事情:它将代码填充到该地址 - 类似于 Nasm 代码中的 times 行。Nasm 可以做这是因为在-f bin 模式下,它“充当自己的链接器”。

    代码要知道的重要一点是可以找到Msg 的地址。 jmps 和 jnes(以及您的示例没有,但编译器可能生成的 callret)是相对寻址模式。我们编码jmp target,但实际发出的字节是jmp distance_to_target(加号或减号),所以地址无关紧要。

    Gas 不会这样做,它会发出一个可链接的目标文件。要在没有链接器脚本的情况下使用 ld,命令行如下所示:

    ld -o boot.bin boot.o -oformat binary -T text=0x7C00

    (不要引用我的确切语法而是“类似的东西”)如果您可以从您的(16 位功能!)C++ 编译器中获得一个可链接的目标文件,您也许可以这样做。

    在引导扇区的情况下,代码由 BIOS(或假 BIOS)在 0x7C00 加载 - 这是我们可以假设的关于引导扇区的少数情况之一。对于 bootsector 来说,明智的做法不是在打印消息时摆弄,而是加载其他内容。您需要知道如何在磁盘上找到其他内容以及要将其加载到何处(可能是您的 C++ 编译器默认将其放置在何处)- 以及jmp 那里。这个jmp 想要成为far jmp,它确实需要知道地址。

    我猜它会是一些丑陋的 C++!

    【讨论】:

      猜你喜欢
      • 2010-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多