-2

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

4 回答 4

1

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

例如:

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

于 2013-04-11T03:24:25.003 回答
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
于 2013-04-13T14:44:04.247 回答
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(系统调用)来将这些字符逐个显示或显示为字符串(您可能需要在这两个字符之后附加一个零字节字符组成一个字符串)。

就这样。

于 2013-04-11T06:48:17.267 回答
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

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

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

cmp al, 0Ah
sbb al, 69h
das

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

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

于 2013-04-12T04:23:55.917 回答