用于将hex转换为dec的汇编代码不起作用

时间:2013-04-23 10:57:31

标签: assembly hex decimal nasm multiplying

我有这个汇编代码(linux 80x86 nasm),假设将十六进制数转换为dec:

    my_func:
    push    ebp
    mov ebp, esp    ; Entry code - set up ebp and esp
    pusha           ; Save registers
    mov dword[LC1],0
    mov ecx,dword[ebp+8]    ; Get argument (pointer to string)

start_loop:
    mov ebx,0       ;zero ebx register
    mov eax,16
    mov edx,0
    mov bl, byte[ecx]   ;bl is the curr number
    jmp bl_to_num   ;change it to be a number

continue:
    add dword[LC1], ebx ;dword[LC1] = dword[LC1]+ebx
    inc ecx
    cmp byte[ecx],0
    je  end_func

    mul dword[LC1]  ;dword[LC1]*eax = edx:eax
    mov     dword[LC1],eax

    jmp start_loop

dword [LC1]是我返回C函数的参数,ecx是指向接收到的字符串的指针。 函数:bl_to_num只是将bl字节转换为数字(a = 10,b = 11 ..) 当我用输入1运行此代码时,我收到输出234。 当我用输入2运行此代码时,我收到输出250。 一个...... 我的错误在哪里? 谢谢!

编辑: 这是bl_to_num:

bl_to_num:
    cmp bl,'A'
    je  con_a
    cmp bl,'a'
    je  con_a

    cmp bl,'B'
    je  con_b
    cmp bl,'b'
    je  con_b

    cmp bl,'C'
    je  con_c
    cmp bl,'c'
    je  con_c

    cmp bl,'D'
    je  con_d
    cmp bl,'d'
    je  con_d

    cmp bl,'E'
    je  con_e
    cmp bl,'e'
    je  con_e

    cmp bl,'F'
    je  con_f
    cmp bl,'f'
    je  con_f

    sub bl,48
    jmp continue
con_a:
      mov   bl,10
      jmp   continue
con_b:
      mov   bl,11
      jmp   continue
con_c:
      mov   bl,12
      jmp   continue
con_d:
      mov   bl,13
      jmp   continue
con_e:
      mov   bl,14
      jmp   continue
con_f:
      mov   bl,15
      jmp   continue

1 个答案:

答案 0 :(得分:3)

您的结果表明您的输入字符串在NULL终止符之前包含换行符(0x0A)。因此,如果您输入'1',则会获得:

第一次迭代:
LC1 += 1
LC1 *= 16 (= 16)

第二次迭代:
LC += zero_extend(10-48)LC += 218 (= 16 + 218 = 234)


您的bl_to_num例程也可以简化:

bl_to_num:
  cmp bl,'9'
  jbe digit
  cmp bl,'F'
  jbe already_uppercase
  sub bl,' '
  already_uppercase:
  sub bl,7
  digit:
  sub bl,'0'
  jmp continue


编辑:我的机器上的以下工作正常(Xeon / Ubuntu 64位):

format: .asciz "%d\n"

.bss
    LC1:  .long 0

.text
.globl main
.type   main, @function
main:

movl  8(%esp),%ecx   # get argv    
movl  4(%ecx),%ecx   # get argv[1] (argv[0] is the program name)

start_loop:
xor  %ebx,%ebx       
movl $16,%eax
xor  %edx,%edx
movb (%ecx),%bl   

sub  $48,%bl     # simplified bl_to_num that handles only '0'..'9'

continue:
add  %ebx,LC1 
inc  %ecx
cmpb $0,(%ecx)
je   end_func

mull LC1  
movl %eax,LC1

jmp  start_loop

end_func:

movl LC1,%eax
pushl %eax
pushl $format       # push the format string
call printf
addl $8,%esp        # pop the arguments

movl $0, %eax    # return value 
ret

$ gcc -m32 -o hexarg hexarg.s
$ ./hexarg 67
103