【问题标题】:hello world in NASM WITHOUT windows api没有 Windows api 的 NASM 中的你好世界
【发布时间】:2014-05-14 18:35:32
【问题描述】:

我一直在使用 NASM 在 Linux 上进行汇编编码,现在我正在尝试在 Windows 上学习同样的方法。按照 Ray Duncan 的高级 MS-DOS 编程,图 3-7 列出了一个基于 MASM 的 hello world 程序,它基本上使用中断 21h 打印“hello world”。这与在 Linux 上使用中断 80h 做同样的事情是同义的,感觉就像在家里一样。我想在 Windows 上使用 NASM 做同样的事情。

网络上的大多数示例使用 Windows API,例如 _GetStdHandle、_WriteConsoleA 等,或者使用 C 库,例如 _printf。我想做它的骨头。沿着以下片段:

global _start

section .data
    str:     db 'hello, world',0xA
    strLen:  equ $-str

section .text
    _start:

mov ah,40h 
mov bx,1 
mov cx, strLen 
mov dx, str
int 21h 

mov ax,4c00h 
int 21h 

希望我没有模棱两可:)

【问题讨论】:

  • 中断 21h 是一个 DOS 调用,因此将在 DOS 下运行。我建议您打开一个 DOS 窗口,然后从那里运行您的程序以查看输出。
  • 32 位 Windows 系统将运行 16 位 DOS 程序,因此如果适合您,您可以使用 Ray Duncan 版本。但是,64 位 Windows 系统不再具有 MS-DOS 子系统/仿真,因此它不会在那里工作。您将需要使用 Windows API,或者如果您更喜欢使用本机 NT API(它们非常相似,但通常没有文档记录)。如果您想使用实际的系统函数调度程序,请查看 Russinovich 的“Windows Internals”一书 - 实际使用的系统调度机制非常依赖于处理器和 Windows 版本。

标签: windows assembly nasm masm


【解决方案1】:

我喜欢从 vitsoft 显示上面代码的一些变化,而不使用软件中断将字符串直接打印到我们必须在下面的代码中指定的给定屏幕坐标。 (但它不会触摸或移动光标位置。)对于 64 位 Windows,请使用 DOSBOX。

; Save as hello.asm, assemble with nasm -f bin -o hello.com hello.asm
ORG       256
Start:    JMP Main
strOfs    DB 'hello, world'
strLen    EQU $-strOfs   ; meaning of $ = offset address of this position in the code
Main:     MOV SI,strOfs  ; offset address of the string
          MOV CX,strLen  ; lenght of the string
          MOV AX, 0B800h ; segment address of the textmode video buffer
          MOV ES, AX     ; store the address in the extra segment register
          MOV DI, (Line_Number*80*2)+(Row_number*2) ; target address on the screen
          CLD            ; let the pointer adjustment step forward for string instructions
nextChar: LODSB          ; load AL from DS:[SI], increment SI
          STOSB          ; store AL into ES:[DI], increment DI
          INC DI         ; step over attribute byte
          LOOP nextChar  ; repeat until CX=0
          MOV AH,00h     ; BIOS function GET KEYSTROKE
          INT 16h        ; Press any key to continue
          RET            ; Exit program

【讨论】:

    【解决方案2】:

    如果 DOS 功能还不够简单,您可以使用 PC 固件中硬连线的 BIOS 功能。它们记录在 Ralf Brown 的中断列表http://www.ctyme.com/rbrown.htm

    ; Save as hello.asm, assemble with nasm -f bin -o hello.com hello.asm
    ORG       256
    Start:    JMP Main
    strOfs    DB 'hello, world',0Ah
    strLen    EQU $-strOfs
    Main:     MOV SI,strOfs
              MOV CX,strLen
              SUB BX,BX ; clear videopage number and color
              MOV AH,0Eh ; BIOS function TELETYPE OUTPUT
              CLD
    nextChar: LODSB ; load AL from [SI], increment SI
              INT 10h ; Display one character, advance cursor position
              LOOP nextChar
              MOV AH,00h ; BIOS function GET KEYSTROKE
              INT 16h ; Press any key to continue
              RET     ; Exit program
    

    【讨论】:

    • 中断由操作系统处理,而不是固件。
    • @Praxeolitic 当然,但这仅在操作系统负责时才是正确的。在它启动之前,BIOS 会初始化中断表以指向它自己的例程,因此它们可以在启动过程中使用。即使在加载 Windows 时,它也会模拟 BIOS 中断的大多数功能。这就是为什么上面的代码可以在引导扇区代码、DOS 和 32 位 Windows 中工作的原因。
    猜你喜欢
    • 2021-11-19
    • 2014-02-27
    • 1970-01-01
    • 1970-01-01
    • 2022-11-04
    • 1970-01-01
    • 2015-01-13
    • 1970-01-01
    相关资源
    最近更新 更多