如何用汇编语言打印字符串

San*_*pte 5 assembly qemu nasm

我正在尝试使用 NASM 在 Q Emulator 中打印一个字符串。我的代码如下:

mov bx,HELLO
mov ah, 0x0e
int 0x10
HELLO:
  db 'Hello', 0
jmp $
times 510-($-$$) db 0
dw 0xaa55
Run Code Online (Sandbox Code Playgroud)

但是,当我编译这段代码时,我得到的输出是

UU
Run Code Online (Sandbox Code Playgroud)

谁能告诉我为什么会这样?以及如何获取所需的字符串作为输出?

提前致谢。

Log*_*ios 4

好吧,这就是你问题的答案

为了加载字符串,您必须将其移至si(并不是真的想深入,但只是这样做)。接下来,为了将字符加载到寄存器 AL 中,请使用lodsb。接下来,我们必须打印它,因此使用 int 10h mov ah, 0Eh。Int 10h 处理视频,ah 告诉 BIOS 打印 al(又名 lodsb)中的任何内容。接下来,我们必须有一个结束加载字符,这样我们就不会永远循环。我个人使用0x00,但你使用 0。在我的情况下,0x00 更好,因为你不仅可以使用 0,0x00 不会打印任何内容,所以你为什么需要它呢?

好的,我们已经完成了所有工作,下面是代码:

    mov si, message ;消息位置*您可以更改此*
    call print ;CALL 告诉电脑完成后跳回到这里

    打印:
      mov ah, 0Eh ;设置功能

    。跑步:
      lodsb ;获取字符
    ; cmp al, 0x00 ;我会使用这个,但你知道你不这么使用:
      cmp al, 0 ;0 的十六进制代码为 0x48,因此它不是 0x00
      je .done ;如果找到结束代码则跳转到done
      int 10h ;否则打印
      跳转.运行; 并跳回 .run

    。完毕:
      ret ;返回

    message db 'Hello, world', 0 ;如果你使用 0x00
    ;消息数据库'你好,世界',0x00

  • “0”(十进制)和“0x00”(十六进制)是相同的数字。“0”是 NASM 语法中“48”或“0x30”的一种写法,也许这就是您在写关于“0”与“0x00”的评论时所想到的?是的,“0”将是一个糟糕的终止符选择,但“0”是 100% 正常的。请注意,它位于带引号的字符串之外,因此它只是一个数字。 (3认同)
  • 使用“lodsb”是循环字符串的*一种*方法;如果您这样做,那么您需要 DS:SI (https://www.felixcloutier.com/x86/lods:lodsb:lodsw:lodsd:lodsq) 中的指针,并将 DS 设置为匹配 ORG 设置(BIOS 不这样做)在引导加载程序中并不总是适合您;在不同的机器上可能存在多个不同的 DS 值,因此您应该在旧版 BIOS 引导加载程序中自行设置 DS,就像问题所写的那样。) (3认同)