string - 使用 nasm 从 dx 打印十六进制

其实我是想用nasm打印dx寄存器的内容。因此,内容是一个 16 位的十六进制数字,例如 0x12AB。

因此我首先实现了一个能够打印字符串的函数:

print_string:
    pusha
    mov ah, 0xe

print_character:
    mov al, [bx]
    inc bx
    or al, al
    jz print_done
    int 0x10
    jmp print_character

print_done:
    popa
    ret

你可以这样使用这个函数:

mov bx, MSG
call print_string

MSG:
    db 'Test',0

现在我想要一个函数,将十六进制转换为字符串,以便 print_string 能够打印它。我在想这样的事情:

print_hex:
    pusha
    mov bx, HEX_OUT
    ; HEX_OUT is a kind of template string
    ; now i want to get the hex of dx into this template in order to be able to print it
    ; However I'm not sure how to manage this
    call print_string
    popa
    ret

HEX_OUT:
    db '0x0000', 0

不幸的是,我不确定如何将十六进制从 dx 分别获取到 bx,即 HEX_OUT。有人可以帮助我或有人有想法吗?

我想在最后像这样使用它:

mov dx, 0x12AA
call print_hex

提前谢谢你!

更新:

如前所述,我可以像这样实现分离和打印:

print_hex:
    pusha
    mov bx, PREFIX
    call print_string

next_character:
    mov bx, dx
    and bx, 0xf000
    shr bx, 4
    add bh, 0x30
    cmp bh, 0x39
    jg add_7

print_character_hex:
   mov al, bh
   mov ah, 0x0e
   int 0x10
   shl dx, 4
   or dx, dx
   jnz next_character
   popa
   ret

add_7
   add bh, 0x7
   jmp print_character_hex

PREFIX:
   db '0x', 0

我尝试用我的函数和缓冲区打印它:

print_hex:
    ;Added this here    
    mov cx, HEX_OUT + 2

print_character_hex:
    mov [cx], bh

虽然由于“无效的有效地址”,我无法组装它。我需要做什么才能做到这一点?

最佳答案

这调整了接受的答案以包括 Kyle G. 对 0 问题的修复。

; vim: :set ft=nasm:

[bits 16]

; subroutine to print a hex number.
;
; ```
; dx = the hexadecimal value to print
; ```
;
; Usage
;
; ```
; mov dx, 0x1fb6
; call print_hex
; ```
;
; used as an answer here: https://stackoverflow.com/a/27686875/7132678
;
print_hex:
        ; push all registers onto the stack
        pusha

        ; use si to keep track of the current char in our template string
        mov si, HEX_OUT + 2

        ; start a counter of how many nibbles we've processed, stop at 4
        mov cx, 0

next_character:
        ; increment the counter for each nibble
        inc cx

        ; isolate this nibble
        mov bx, dx
        and bx, 0xf000
        shr bx, 4

        ; add 0x30 to get the ASCII digit value
        add bh, 0x30

        ; If our hex digit was > 9, it'll be > 0x39, so add 7 to get
        ; ASCII letters
        cmp bh, 0x39
        jg add_7

add_character_hex:
        ; put the current nibble into our string template
        mov [si], bh

        ; increment our template string's char position
        inc si

        ; shift dx by 4 to start on the next nibble (to the right)
        shl dx, 4

        ; exit if we've processed all 4 nibbles, else process the next
        ; nibble
        cmp cx, 4
        jnz next_character
        jmp _done

_done:
        ; copy the current nibble's ASCII value to a char in our template
        ; string
        mov bx, HEX_OUT

        ; print our template string
        call print_string

        ; pop all arguments
        popa

        ; return from subroutine
        ret

add_7:
        ; add 7 to our current nibble's ASCII value, in order to get letters
        add bh, 0x7

        ; add the current nibble's ASCII
        jmp add_character_hex

; our global template string. We'll replace the zero digits here with the
; actual nibble values from the hex input.
HEX_OUT:
        db '0x0000', 0

此外,值得注意的是,这是来自 https://www.cs.bham.ac.uk/~exr/lectures/opsys/10_11/lectures/os-dev.pdf 的练习。 ,第 3.5.1 节,问题 5,第 23 页。

https://stackoverflow.com/questions/27636985/

相关文章:

python - pymssql : Inserting mutliple values into

xaml - String.format xaml 电话号码

c# - 自动实现的属性 setter 上的条件断点

javascript - Code.gs 中的 Google Apps 脚本返回对象

django - 如何从 Django 中的信号获取返回响应

android - 有没有办法知道设备中蓝牙芯片的详细信息?

python - 如何移动 Canvas 多边形?

visual-studio-2013 - 即使通过 NuGet 安装,SpecFlow 也找不到包

php - 在 app.yaml Google App Engine 中将参数传递给 php

javascript - 单击播放音频时出现不必要的延迟