【问题标题】:how to find number of digits in assembly 8086?如何查找程序集 8086 中的位数?
【发布时间】:2013-04-21 20:06:52
【问题描述】:

我是一个新的汇编程序员,我无法成功找到一个数字有多少位。我的目的是找到阶乘。 我在程序集 8086 的模拟器中编程。

【问题讨论】:

  • 是否有指令可以对数字进行base10对数?
  • 看看这个理论:stackoverflow.com/q/6655754/1353098。在实践中,我认为没有 log10 的说明。您是否有权访问任何可能公开此函数的库(如 c 库或数学库)
  • x87 在这里可能会派上用场。日志是浮点处理器更可能拥有的东西。我认为FYL2X 可能是您的指示。
  • 抱歉,您能否详细说明“查找阶乘”的含义?我不确定如何找到位数。
  • 只需除以 10 直到为零。数一数。

标签: math assembly x86 x86-16 digits


【解决方案1】:

执行此操作的最有效方法是使用bsr 指令(参见此slides,20 到25)。

这应该是这样的代码:

    .text
    .globl  main
    .type   main, @function
main:
    movl    $1024, %eax ;; pushing the integer (1024) to analyze
    bsrl    %eax, %eax  ;; bit scan reverse (give the smallest non zero index)
    inc     %eax        ;; taking the 0th index into account

但是,我猜你需要以 10 为底的日志,而不是以 2 为底的日志……所以,这里是代码:

    .text
    .globl  main
    .type   main, @function
main:
    movl    $1024, %eax ;; pushing the integer (1024) to analyze
    bsrl    %eax, %eax  ;; bit scan reverse (give the smallest non zero index)
    inc     %eax        ;; taking the 0th index into account

    pushl   %eax        ;; saving the previous result on the stack

    fildl   (%esp)      ;; loading the previous result to the FPU stack (st(0))
    fldlg2              ;; loading log10(2) on the FPU stack
    fmulp   %st, %st(1) ;; multiplying %st(0) and %st(1) and storing result in %st(0)

    ;; We need to set the FPU control word to 'round-up' (and not 'round-down')
    fstcw  -2(%esp)      ;; saving the old FPU control word
    movw   -2(%esp), %ax ;; storing the FPU control word in %ax
    andw   $0xf3ff, %ax  ;; removing everything else
    orw    $0x0800, %ax  ;; setting the proper bit to '1'
    movw   %ax, -4(%esp) ;; getting the value back to memory
    fldcw  -4(%esp)      ;; setting the FPU control word to the proper value

    frndint              ;; rounding-up

    fldcw  -2(%esp)      ;; restoring the old FPU control word

    fistpl (%esp)        ;; loading the final result to the stack
    popl   %eax          ;; setting the return value to be our result

    leave
    ret

我很想知道是否有人能找到比这更好的!事实上,使用 SSE 指令可能会有所帮助。

【讨论】:

  • 值得一提的是,BSR 需要 386,因此对于受问题中提到的 8086 限制的未来读者来说,它将无法使用。 (不幸的是,有些学校使用 emu8086 教授 asm。)知道有效的以 2 为基数的位数可以使您在正确的以 10 位数为基数的数量之内,因此您可以制作以 10 为基数的查找表和比较阈值将其增加 1 或不增加。
  • FP 技巧:您可以不改变舍入模式,而是减去 32 或其他值使其为负数,然后将(带截断)转换为整数,例如SSE cvttss2si eax, xmm0 或 SSE3 fisttp 并撤消偏差。您可以测试所有 32 或 64 个可能的 BSR 结果;如有必要,如果舍入误差方向错误,则将 log10(2) 常数向上或向下调整 1ulp,并在不应该的情况下将其推高超过下一个整数。 (使用 SSE,无论如何您都必须在内存中定义自己的 log10_2 常量。)
猜你喜欢
  • 1970-01-01
  • 2021-12-18
  • 1970-01-01
  • 2022-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多