我正在寻找一个程序,它将1和0的字符串转换为程序集中的十六进制字符串,其中二进制字符串来自我用'C‘编写的代码。
例如:
10111111100-> "5 F C"问题是,对于超过12个字符的输入,输出是错误的,我的任务最多需要32个字符。
例如,给定110010101111->“咖啡馆”,它工作正常!但是给10010001101000101011001111000应该是"12345678“,但是我只能使用gdb工具进行"123”调试,我看到这些值正在被覆盖。如何用代码中的最小变化来处理这个问题?谢谢
其思想是将ecx指向的字符串转换为eax中的值。现在,我希望每次都能得到最正确的4个,并将它们转换到edx中。
到目前为止,我已经:
section .rodata
LC0:
DB "The result is: %s", 10, 0 ; Format string
section .bss
LC1:
RESB 32
section .text
align 16
global my_func
extern printf
my_func:
push ebp
mov ebp, esp ; Entry code - set up ebp and esp
pusha ; Save registers
mov ecx, dword [ebp+8] ; Get argument (pointer to string)
mov ebx, 0 ; counter for length
mov eax, 0 ; will hold the string as a value
mov edx, 0 ; manipulation helper
mov edi, 0 ; counter for ehile_length loop
length:
inc ebx
cmp byte [ecx+ebx], 0x00
jne length
dec ebx
;;;;THIS PART IS PARSING THE STRING INTO A REGISTER;;;
bring_ecx_to_end:
inc ecx
cmp byte [ecx], 0x0
JNE bring_ecx_to_end
dec ecx
dec ecx
or edi ,ebx
add esi,1
while_length:
mov dl,byte [ecx] ; gets 1 char into edx
cmp DL, 0x31 ; the right character
JE inc1 ; if it a '1'
resume_loop:
shl esi,1 ; multiply by 2
dec ecx
sub edi,1
cmp edi,0
jne while_length
;;;;;;;;;;NOW EAX CONSISTS THE STRING ;;;;;;;;;;;;;;
mov dword edx,0 ;target register
while:
mov dword edi ,0
add edi ,15 ; masking
and edi,eax
cmp di , 10
jl less_than_10
;less_than_F
add di ,55
jmp resume
less_than_10:
add di ,48
resume:
or edx,edi
shl edx,8
shr eax,4
cmp al ,0
jne while
shr edx , 8
;;;;;;;;;DONE;;;;;;;;;;;;;
end:
mov dword [LC1],edx
push LC1 ; Call printf with 2 arguments: pointer to str
push LC0 ; and pointer to format string.
call printf
add esp, 8 ; Clean up stack after call
popa ; Restore registers
mov esp, ebp ; Function exit code
pop ebp
ret
inc1:
or eax, esi
jmp resume_loop发布于 2015-03-29 13:23:35
如果要将零和1的字符串转换为字符串 ("10111111100“-> "000005FC"),那么首先要做的就是将源字符串的值放入寄存器中。您需要设置ECX以指向字符串LC1。
mov ecx,[ebp+8] ;Pointer to an ASCIIZ string of zero and one characters.
xor ebx,ebx
First:
rcl ebx,1
mov al,[ecx]
inc ecx
shr al,1
jnz First
mov ecx,LC1 ;Buffer to recieve 8 hexcharacters.
Again:
rol ebx,4您可以将代码shl al,4 shr al,4简化为and al,15。
end:
shr ebx, 4
inc ecx ; increment pointer
cmp byte [ecx], 0 ; check if byte pointed to is zero
jnz while_ebx_not_zero ; keep looping until it is null 端部不应改变EBX,精确跳回8次。
end:
inc ecx
cmp ecx,LC1+8
jb Again发布于 2015-03-29 13:33:38
语法明白了。(地球上的每个人都这样做过,其中包括我无数次。)
cmp al , 00001001 ;This is actually one thousand and one
jz case1001to9 ;but you treat it like it's nine我不知道您是否在使用Masm/Tasm/Nasm/或其他什么,但是我相信,如果您将字母"b“放在二进制数字的末尾,Masm就会认出它们。
(噢,编辑:结尾的字母B是老派。刚检查了微软网站上的这里和新的改进版(不是,但我没有投票权),方法是将"0y“作为前缀,而不是我原先建议的"B”作为后缀。
让我的话进行测试:在这样做之前,先看看汇编程序的输出,看看00001001实际上是9还是1,001。
如果无法在汇编程序中看到输出,请逐步调试。
发布于 2015-03-29 15:11:29
任何长度输入的另一个变体。该代码是16位,可能会被优化一点。写在膝盖上,来展示这个想法
mov si, input_string
mov di, output_string
mov ax, 7 ;input_string length
call bin2hex
bin2hex:
add si, ax ;si points to the end of input string
mov bx, ax
mov cx, 4 ;\
div cl ;
cmp ah, 0 ;compute how many nibbles to convert
jz short .a ;and point di to the end of the result buffer
inc di ;
mov ah, 0 ;
.a: ;
add di, ax ;/
mov [di], ah ;terminating zero
.next_nibble:
mov cl, 4 ;iterate 4 times
mov dl, 0
.next_bit:
dec si
mov al, [si]
shr al, 1 ;mov bit0 to carry flag
rcl dl, 1 ;shift with carry flag into the least-significant bit
dec bx
jz short .stop ;end of input string?
dec cx
jnz short .next_bit
.stop:
shl dl, cl ;complete last nibble to full
cmp dl, 0x0a
jl short .to_ascii
add dl, 7 ;0Ah - 0Fh = ASCII codes 41h - 46h
.to_ascii:
add dl, 0x30
dec di
mov [di], dl
test bx, bx ;end of input string reached?
jnz .next_nibble ;continue if not
rethttps://stackoverflow.com/questions/29328840
复制相似问题