首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在程序集80x86中将二进制转换为十六进制

在程序集80x86中将二进制转换为十六进制
EN

Stack Overflow用户
提问于 2015-03-29 12:01:18
回答 3查看 7.3K关注 0票数 0

我正在寻找一个程序,它将1和0的字符串转换为程序集中的十六进制字符串,其中二进制字符串来自我用'C‘编写的代码。

例如:

代码语言:javascript
复制
10111111100-> "5 F C"

问题是,对于超过12个字符的输入,输出是错误的,我的任务最多需要32个字符。

例如,给定110010101111->“咖啡馆”,它工作正常!但是给10010001101000101011001111000应该是"12345678“,但是我只能使用gdb工具进行"123”调试,我看到这些值正在被覆盖。如何用代码中的最小变化来处理这个问题?谢谢

其思想是将ecx指向的字符串转换为eax中的值。现在,我希望每次都能得到最正确的4个,并将它们转换到edx中。

到目前为止,我已经:

代码语言:javascript
复制
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
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-03-29 13:23:35

如果要将零和1的字符串转换为字符串 ("10111111100“-> "000005FC"),那么首先要做的就是将源字符串的值放入寄存器中。您需要设置ECX以指向字符串LC1。

代码语言:javascript
复制
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

代码语言:javascript
复制
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次。

代码语言:javascript
复制
end:
inc ecx
cmp ecx,LC1+8
jb Again
票数 2
EN

Stack Overflow用户

发布于 2015-03-29 13:33:38

语法明白了。(地球上的每个人都这样做过,其中包括我无数次。)

代码语言:javascript
复制
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。

如果无法在汇编程序中看到输出,请逐步调试。

票数 2
EN

Stack Overflow用户

发布于 2015-03-29 15:11:29

任何长度输入的另一个变体。该代码是16位,可能会被优化一点。写在膝盖上,来展示这个想法

代码语言:javascript
复制
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
  ret
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29328840

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档