【问题标题】:Assembly 8088 - converting to hexadecimal程序集 8088 - 转换为十六进制
【发布时间】:2013-04-11 03:21:02
【问题描述】:

我正在尝试编写汇编代码来执行文件 hexdump,就像在 Linux 中从命令行执行“hexdump -C sample.txt”一样。我已经打开文件并将内容读入缓冲区,但我无法超越,试图将这些字节转换为十六进制。

任何帮助将不胜感激。

   _WRITE   = 4                !System call number for WRITE        
   _READ    = 3                !System call number for READ    
   _OPEN    = 5                !System call number for OPEN
   _EXIT    = 1                !System call number for EXIT
   _GETCHAR = 117                !System call number for GETCHAR
   _PUTCHAR = 122                !System call number for PUTCHAR
   _PRINTF  = 127                !System call number for PRINTF
   _SPRINTF = 121                !System call number for SPRINTF
   _SSCANF  = 125                !System call number for SSCANF
   _OPEN    = 5                !System call number for OPEN

   bufsiz  = 512                !bufsiz = 512

   .SECT .TEXT                !Start label
    start:     
    MOV BP, SP            !System trap instruction
    MOV CX, de-greet
    PUSH CX
    PUSH greet
    PUSH _PRINTF
    SYS
    ADD SP, 8

    CALL GetFileInput

    Byte2Hexadecimal:

    !Conversion needs to take place here



    Word2Hexadecimal:


      !From Word to Hexadecimal needs to take place here 




    GetFileInput:
    PUSH BP
    MOV BP,SP
    MOV DI, buf
    PUSH _GETCHAR

    next_char:SYS
    CMPB AL, '\n'
    STOSB
    JNE next_char
    JL 9f
    JE 1f
        MOVB (DI),0
        POP AX
        POP BP 
        RET

    PUSH 0
    PUSH buf
    PUSH _OPEN
    SYS
    CMP AX,0
    JL 9f
    MOV (fildes),AX
    MOV SI,linh+2
    MOV BX,0

     1: CALL fillbuf
    CMP CX, 0
    JLE 3f
     2: MOV        

      9: MOV SP,BP
     PUSH buf
     PUSH errmess
     PUSH _PRINTF
     SYS
     PUSH _EXIT
     PUSH _EXIT
     SYS     

    OpenFile:


    fillbuf:
    PUSH bufsiz
    PUSH buf
    PUSH (fildes)
    PUSH _READ
    SYS
    ADD SP,8
    MOV CX,AX
    ADD BX,CX
    MOV DI,buf
    RET


   .EXIT: 
    PUSH 0                !Return code
    PUSH _EXIT            !Return to OS
    SYS                !System trap instruction

    .SECT .DATA
    errmess:     .ASCIZ "Open %s failed\n"
    numfmt:         .ASCIZ "%d"
    greet:         .ASCIZ "Welcome to our program, please enter the file name: \n"
    de:         .BYTE 0

   .SECT .BSS
    linh: .SPACE 8192        !
    fildes: .SPACE 2        !Memory location for the fildes 
     byte1:    .SPACE 8        !Memory location for the Byte 
    addr:    .SPACE 8        !Memory location for the address
    word:   .BYTE  2          !Memory location for the byte 
    buf:     .SPACE 80        !Memory location for the BUFF
    buffer: .SPACE bufsiz+2        

【问题讨论】:

  • 显示一些代码。我们不是来为你做你的工作的。但如果你有一些实际的代码,我们会尽力帮助解决这个问题。
  • 我已经在上面包含了汇编代码。这就是我已经走了多远。在这些子例程中,需要转换。关键是我不能自己生成代码。我只需要子程序的帮助,代码会有所帮助

标签: assembly x86 x86-16


【解决方案1】:

没有“将字节转换为十六进制”之类的东西。实际数据是不变的,由二进制 1 和 0 组成。根据您的需要,您对这些位的解释可能会有所不同。例如,它可以解释为文本字符或十进制或十六进制或任何值。

例如:

Binary 01010101 = decimal 85 = hexadecimal 55 = octal 125 = 'U' ASCII character.

【讨论】:

  • 您需要编写自己的子程序来将每个字节转换为相应的 ASCII 十六进制数字。创建一个名为 Byte2Hexadecimal 的子程序,它接受两个参数:要转换的字节和将写入两位十六进制字符串的缓冲区的地址。这些参数应该通过堆栈以相反的顺序传递。
【解决方案2】:

一个粗略而简单的实现是将字节分成两个半字节,然后将每个半字节用作十六进制字符“表”的索引。

; cdecl calling convention (google if you're not familiar with)

HEX_CHARSET        db '0123456789ABCDEF'


; void byteToHex(byte val, char* buffer)
proc byteToHex
    push bp
    mov bp,sp
    push di

    mov dx,[word ptr ss:bp + 4] ; the address of val
    mov di,[word ptr ss:bp + 6] ; the address of buffer

    ; high nibble first
    mov ax,dx
    mov cl,4
    shr al,cl
    push ax
    call nibbleToHex
    add sp,4
    stosb

    ; low nibble second
    mov ax,dx
    push ax
    call nibbleToHex
    add esp,4
    stosb

    pop di
    mov sp,bp
    pop bp
    ret
endp byteToHex


; char nibbleToHex(byte nibble)
proc nibbleToHex
    push bp
    mov bp,sp
    push si

    mov ax,[word ptr ss:bp + 4]
    and ax,0Fh    ; Sanitizing input param
    lea si,[ds:HEX_CHARSET]
    add si,ax
    lodsb

    pop si
    mov sp,bp
    pop bp
    ret
endp nibbleToHex

【讨论】:

    【解决方案3】:

    一个十六进制数字有 4 位。一个字节有 8 位或 2 个十六进制数字。

    要以十六进制显示一个字节,您需要将这两个 4 位半部分中的每一个分开,然后转换每个部分的结果值(不出所料,将从 0 到 24- 1、IOW,从0到15或者从0到0FH)到对应的ASCII码:

    0 -> 48(或 30H 或“0”)
    1 -> 49(或 31H 或“1”)
    ...
    9 -> 57(或 39H 或 '9')

    10(或 0AH)-> 65(或 41H 或 'A')
    11(或 0BH)-> 66(或 42H 或“B”)
    ...
    15(或 0FH)-> 70(或 46H 或“F”)

    将一个字节转换为两个 ASCII 字符后,您可以调用操作系统的相应 API(系统调用)来将这些字符逐个显示或显示为字符串(您可能需要附加一个零字节在这两个字符之后组成一个字符串)。

    就是这样。

    【讨论】:

    • 你可以调用适当的 Linux API”——为什么要假设 Linux?
    • @icepack 有些东西让我觉得是 Linux。你是对的,它是任何操作系统。已更新。
    • 这是什么汇编程序? (as86?)什么操作系统?我认为我不熟悉我们推送等于_PRINTF 的系统调用号并执行SYS 的任何系统。我很困惑!无论如何,相同的算法。我喜欢rol 来获得我的4 位(如果真的是8086,可能只有1cl 用于移位/旋转计数)。你会想要制作一个副本,因为你必须屏蔽掉 4 位。然后添加“0”,如果大于“9”,则添加另一个 7。OTOH,如果您有%d,那么%X 可能会解决您的问题。真正的“hexdump”在右侧打印 ascii - 不要尝试打印少于 20 小时的任何内容!
    • @FrankKotler 什么操作系统和什么汇编程序——你可能应该向 OP 询问它。无论如何,SYS 可以是扩展为 INT SomeNumberCALL SomeFunction 或类似的宏。
    • 嗨,阿列克谢。我在问 OP - 在我阅读你的评论之前写了我的评论。你能想到int somenumbercall somefunction 可以做到这一点的任何系统吗?我想可能是自制的!
    【解决方案4】:

    说明明确指出您应该自己编写此代码!

    ; push ax  ; byte in al
    ; push outbuf
    ; call Byte2Hexadecimal
    ; add sp, 4
    
    Byte2Hexadecimal:
        push bp
        mov bp, sp
        push di
        mov di, [bp + 4]  ; buffer to put it
        mov ax, [bp + 6]  ; we're only interested in al
        mov ah, al  ; make a copy
        mov cl, 4  ; ASSume literal 8086
        shr al, cl   ; isolate high nibble first
        add al, '0'  ; '0'..'9'
        cmp al, '9'  ; or...
        jbe skip
        add al, 7  ; 'A'..'F'
    skip:
        stosb
        mov al, ah  ; restore our al from copy
        and al, 0Fh  ; isolate low nibble
        add al, '0'  ; etc...
        cmp al, '9'
        jbe skip2
        add al, 7
    skip2:
        stosb
        pop di
        mov sp, bp
        pop bp
        ret
    

    未经测试(!)......类似的东西......(可能想要零终止(或'$'终止?)你的缓冲区)。

    将半字节转换为十六进制 ascii 的极短方法

    cmp al, 0Ah
    sbb al, 69h
    das
    

    你可能不想弄清楚那个...而且das 无论如何都是狗慢...

    现在:什么汇编程序?什么操作系统?

    【讨论】:

      猜你喜欢
      • 2017-07-19
      • 1970-01-01
      • 1970-01-01
      • 2018-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-28
      • 2014-12-31
      相关资源
      最近更新 更多