【问题标题】:NASM prints two strings at a time when i only want one at a time?当我一次只需要一个字符串时,NASM 一次打印两个字符串?
【发布时间】:2017-10-22 06:20:19
【问题描述】:

我使用 nasm 一次打印一个字符串,但它一次打印两个字符串,我在末尾添加了空字符,我正在比较空字符以检查字符串的结尾,但两个字符串即使我只要求其中一个,最终也会被打印出来。

[org 0x7c00]

mov bx, HELLO_MSG
call print_string

mov bx, GOODBYE_MSG

jmp $

%include "print_string.asm"

;Data
HELLO_MSG:
db 'Hello, World!',0

GOODBYE_MSG:
db 'GOODBYE!',0

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

另一个文件 print_string.asm

print_string:
pusha
cld
mov ah,0x0e

 config:    mov al,[bx]
            ;Comparing the strings
            mov cx,[bx]
            cmp cx,0x00 ;Comparing for null
            jne print
je end

print:  int 0x10
        add bx,1
        jmp config

end:    popa
        ret

【问题讨论】:

  • mov cx,[bx] 该指令读取 bx 处的 WORD(即 2 个字节)。由于没有 WORD 为 0,因此此循环永远不会结束。
  • 只是一个观察。 pusha/popa 是 80186 指令。如果编写可能针对多种硬件的引导加载程序,则应该只考虑 8086 指令。当然,如果目的是引导受保护模式的内核,那么这不是问题。您还应该显式设置 DS 段寄存器并使用 CLD 确保字符串指令向前移动。这些是对现有答案的观察。
  • @DavidWohlferd 感谢您的洞察力。我将该代码更改为。 config: mov al,[bx] ;Comparing the strings cmp byte [bx],0x00 ;Comparing for null jne print je end 它正在工作

标签: assembly nasm


【解决方案1】:
; ds:si = asciiz string pointer
print_string:
    pushf            ; store everything to be modified
    push ax
    push bx
    push si
    cld
    mov ah,0x0e
    xor bx,bx        ; bh (page) = 0, bl (color in gfx modes only)
 print_string_loop:
        lodsb
        ; check for null-terminator of string
        test al,al
        jz  print_string_end
        int 0x10
        jmp print_string_loop
 print_string_end:
    pop  si      ; restore everything
    pop  bx
    pop  ax
    popf
    ret

; other code must be adjusted to put pointer into SI, not BX!

这显示common x86 asm idiom 测试零值。

我将字符串指针从bx 移动到si,因为这样我可以使用lodsb 加载al(包括si 的增量),并避免@987654331 @,因为bhblint 10h,ah=0Eh 的输入参数。因此,您的旧代码会意外显示任何内容,如果您的字符串地址将加载 bh 并带有一些不可见的有效页码(默认情况下,第 0 页在文本模式下可见),您将不会在屏幕上看到您的字母.

另外,您肯定不会那么着急,以至于您无法保持标签有意义,并坚持使用某种缩进样式(我试图猜测我的答案是什么,不确定我是否成功)。我知道当你只是在做实验时,保持它的整洁有点困难,但在发布 SO 问题之前,最好退后一步,尽可能多地清理以获取Minimal, Complete, and Verifiable example阅读源代码 尽可能容易地吸引尽可能多的人来尝试检查您的问题。从长远来看,在您的代码运行后进行清理也有助于节省您的时间。

【讨论】:

  • 对不起,我的意思是把我的评论放在问题而不是你的答案下面。
  • @MichaelPetch 将其修复为普通的 push/pop 并且由于它我意识到我没有在我的答案中设置 bx,这是一种错误(或功能,因为它是调用者,但未计划的功能)。
  • 在得到您的回答 3 小时后,OP 提出了另一个问题,我为此写了一个 answer。他继续使用他有问题的print_string。让我想知道我们为什么还要打扰......
  • @SepRoland 最终它会咬他,他可能仍然认为“什么时候输出正确的东西,它才有效”,这似乎是新 asm 程序员如此幼稚的自然错误...... :)而且体验过的不行,如果他们能看到我这些年见过的bug... :) 但不可能展示给他们,他们将不得不自己打。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多