地址相差两个字节

时间:2019-08-17 00:52:11

标签: assembly x86 macros nasm bootloader

每当我用nasm boot.asm -o boot.bin汇编脚本时,一切工作正常,除了字符串的位置偏离几个字节。

这是我的boot.asm的样子:

[org 0x7C00]
[bits 16]

%include "stack.mac"
%include "string.mac"
%include "prepareenv.mac"

SECTION .text
GLOBAL _entry

_entry:
  prepareenv _entry

  PUSH message
  PUSH strlen(message)
  CALL _putchars

  JMP $

string message, db "Running."

%include "putchars.asm"

times 510-($-$$) db 0
dw 0xAA55

这基本上就是我的putchars.asm的样子(pushm和rpopm是宏,它们针对每个参数扩展为单独的push和pop。它们生活在stack.mac中):

%ifndef _PUTCHARS_
%define _PUTCHARS_

%include "stack.mac"

; Arg 0: word(2) String address
; Arg 1: word(2) String length
_putchars:
  PUSH EBP
  MOV EBP, ESP
  pushm AX, BX, CX, SI

  MOV SI, [EBP + 4] ; Load string address
  MOV CX, [EBP + 6] ; Load string length

  MOV AH, 0x0E ; Print function
  XOR BX, BX   ; Zero BX

  _putchars_print_loop:
    MOV AL, [SI + BX]         ; Move current character into string
    CMP BX, CX                ; Have we reached the full string length?
    JE  _putchars_ret         ; If so, we can terminate
    INT 0x10                  ; Interrupt to BIOS
    INC BX                    ; Increment BX
    JMP _putchars_print_loop  ; Repeat string loop

  putchars_ret:
    rpopm AX, BX, CX, SI
    POP EBP
    RET 4

%endif

这是我的string.mac的样子:

%ifndef _STRING_
%define _STRING_

%macro string 2+
  %{1}: %{2}
  %{1}_length equ ($ - %{1})
%endmacro

%define strlen(name) name%+_length

%endif

prepareenv.mac仅清除所有段寄存器。删除它不会改变任何东西,因此不重要。

boot.asm命中PUSH message时,加载的地址是字符串实际在内存中开始之前的2个字节。无论字符串如何,这种情况都会发生,并且会在我包含的任何其他文件中发生(我有其他脚本,但是我将其剥离到此处发布的内容,并且具有相同的行为)

我怀疑是NASM中的错误,但是一种变通方法(如果可能)会很好。

0 个答案:

没有答案