2

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

    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
4

1 回答 1

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

于 2013-04-23T12:05:28.200 回答