我正在尝试编写汇编代码来执行文件 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
答案 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
无论如何都是狗慢......
现在:汇编程序是什么?什么操作系统?