程序集8088 - 转换为十六进制

时间:2013-04-11 03:21:02

标签: assembly x86 x86-16

我正在尝试编写汇编代码来执行文件 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        

4 个答案:

答案 0 :(得分:1)

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

E.g:

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

答案 1 :(得分:1)

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

; 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

答案 2 :(得分:0)

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

要以十六进制显示一个字节,您需要将这两个4位半中的每一个分开然后转换每个的结果值(不出所料,将从0到2 4 - 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(系统调用),逐个显示这些字符或作为字符串显示(您可能需要附加一个零字节)在这两个字符之后做一个字符串)。

就是这样。

答案 3 :(得分:0)

指示明确说你应该自己写这个!

; 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

; 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
你可能不想想出那个...而且cmp al, 0Ah sbb al, 69h das 无论如何都是狗慢......

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