如何在汇编中进行 64 位乘 64 位除法?

2023-12-09

如何在 x86 汇编中实现 64 位乘 64 位除法?
我已经启用了扩展寄存器.386指示。


EDX:EAX 中的 64 位值除以 ECX:EBX 中的 64 位值的无符号除法

在 32 位 x86 CPU 上,the div操作说明可以将 EDX:EAX 中的 32 位值除以任何 32 位值。如果我们保持被除数扩展 (EDX) 中的值小于 32 位除数,我们甚至可以(成功)除 EDX:EAX 中大于 32 位的值。
所以,如果我们想要能够划分any64 位值any其他 64 位值,我们需要为其编写代码。这个答案将使用一种名为除以部分商,又称为分块.

所提出的算法不会击败内部算法div操作说明

即使您使用 64 位数据类型,实践告诉我,(通用)程序中的大多数除法仍然可以仅使用内置的div操作说明。这就是为什么我在代码中添加了一个检测机制作为前缀,该机制检查 ECX:EBX 中的除数是否小于 4GB(因此适合 EBX),以及 EDX 中的除数扩展是否小于 EBX 中的除数。如果满足这些条件,则正常div指令可以完成这项工作,而且速度也更快。如果出于某种原因(例如学校)使用div不允许,那么只需删除前缀代码就可以了。

所描述的算法

代码试图尽快摆脱特殊情况:

  • 如果除数为零,则退出并设置进位标志 (i)。
  • 如果被除数为零,则退出时商和余数都设置为零 (ii)。
  • 如果被除数小于除数,我们将以零商和等于被除数的余数退出 (iii)。

The .BSR(BitScanReverse)子程序使用the bsr操作说明查找被除数和除数中 ON 的最高位:

  • 如果返回 SET 零标志,这只能发生在除数上,因为我们之前消除了零除数 (i),我们得出结论,除数为零,然后退出 (ii)。
  • 如果我们得到的被除数小于除数,我们就得出除法毫无意义的结论,然后退出 (iii)。
  • 如果我们得到的被除数等于除数,我们就知道除数与被除数一致。无需换档。
  • 如果我们得到的被除数大于除数,我们就开始将除数向左移动,使其与被除数对齐。

此时的除数已成为一系列试减中使用的第一个值:

  • 对于每次成功的减法,我们都会在尝试构建的商中设置一个匹配位。换句话说:我们加上一个部分商。如果此时当前的股息变为零,我们就完成了,否则我们继续循环。
  • 另一方面,如果减法失败,我们首先恢复当前被除数,然后再继续循环。
  • 循环继续,将当前除数减半。一旦当前除数回到其原始值(并用于试减),我们就不应该再将其减半,而应将当前除数中剩下的部分视为最终余数。
; ------------------------------
; Restoring
; IN (edx:eax,ecx:ebx) OUT (edx:eax,ecx:ebx,CF)
uDiv:   test    ecx, ecx
        jnz     .uDiv
        cmp     edx, ebx
        jnb     .uDiv
        div     ebx             ; EDX:EAX / EBX --> EAX Quotient, EDX Remainder
        mov     ebx, edx        ; Remainder to ECX:EBX
        xor     edx, edx        ; Quotient to EDX:EAX
        ret                     ; CF=0
; - - - - - - - - - - - - - - -
; IN (edx:eax,ecx:ebx) OUT (edx:eax,ecx:ebx,CF)
.uDiv:  push    esi edi
        mov     esi, ebx
        or      esi, ecx
        stc
        jz      .NOK            ; (i) Division by 0

        xor     edi, edi
        push    edi edi         ; (1) 64-bit Quotient under construction
        call    .BSR            ; -> ESI ZF
        jz      .NIL            ; (ii) Dividend is 0
        mov     edi, esi        ; Save position highest set bit in Dividend
        xchg    ebx, eax        ; -> ECX:EBX is Dividend, EDX:EAX is Divisor
        xchg    ecx, edx
        call    .BSR            ; -> ESI ZF=0 (because we know Divisor <> 0)
        sub     edi, esi        ; Delta between positions of highest set bits
        jb      .OK             ; (iii) Small Dividend / Big Divisor
        jz      .d              ; No shifting required
        cmp     edi, 32         ; Shift up Divisor so it aligns with Dividend
        jb      .a
        xchg    edx, eax        ; Before EDX was 0
.a:     xchg    ecx, edi
        shld    edx, eax, cl    ; CPU uses CL Mod 32
        shl     eax, cl
        xchg    ecx, edi

        jmp     .d
.b:     add     ebx, eax        ; Restore Dividend after failed subtraction
        adc     ecx, edx
.c:     dec     edi
        js      .OK             ; We're (back) at the original Divisor
        shr     edx, 1          ; Next try a smaller Divisor (/2)
        rcr     eax, 1
.d:     sub     ebx, eax        ; Try subtracting Divisor from Dividend
        sbb     ecx, edx
        jb      .b              ; Cannot
        bts     [esp], edi      ; -(1)- Add partial quotient
        mov     esi, ebx        ; Is Dividend reduced to zero ?
        or      esi, ecx
        jnz     .c              ; Not yet

.NIL:   xor     ebx, ebx        ; Zero Remainder
        xor     ecx, ecx
.OK:    pop     eax edx         ; (1) EDX:EAX is Quotient, ECX:EBX is Remainder
        clc
.NOK:   pop     edi esi
        ret
; - - - - - - - - - - - - - - -
; IN (edx:eax) OUT (esi,ZF)
.BSR:   xor     esi, esi
        test    edx, edx
        jnz     @f
        bsr     esi, eax        ; -> ESI=[0,31] ZF
        ret
@@:     bsr     esi, edx        ; -> ESI=[0,31] ZF=0
        add     esi, 32         ; -> ESI=[32,63] ZF=0
        ret
; ------------------------------

例如:34 / 5

被除数 34 是 00100010b,除数 5 是 00000101b。
它将产生商 00000110b (6) 和余数 00000100b (4)。
当然,二进制表示法还多了 56 个零位!

    Aligned
    v
  00100010 (34)
- 00101000 (40) Divisor << 3
  --------
  11111010 (-6) NOK ---------------> Quotient = 00000000
+ 00101000 (40) Restore
  --------
  00100010 (34)
- 00010100 (20) Divisor << 2
  --------                  \----------->-----------\
  00001110 (14) OK ----------------> Quotient = 00000100
- 00001010 (10) Divisor << 1
  --------                  \----------->------------\
  00000100 ( 4) OK ----------------> Quotient = 00000110
- 00000101 ( 5) Divisor << 0
  --------
  11111111 (-1) NOK ---------------> Quotient = 00000110 (6)
+ 00000101 ( 5) Restore
  --------
  00000100 ( 4) Remainder

一个优化

一个不错的改进是,在减法失败的情况下不必恢复股息。
与之前相同的示例:34 / 5
我们现在结合恢复添加plus 40进一步减法minus 20进入单一加法plus 20.
当然,最后,当不再进行减法时,我们仍然需要最后的恢复来获得余数。

    Aligned
    v
  00100010 (34)
- 00101000 (40) Divisor << 3
  --------
  11111010 (-6) NOK ---------------> Quotient = 00000000
+ 00010100 (20) Divisor << 2
  --------                  \----------->-----------\
  00001110 (14) OK ----------------> Quotient = 00000100
- 00001010 (10) Divisor << 1
  --------                  \----------->------------\
  00000100 ( 4) OK ----------------> Quotient = 00000110
- 00000101 ( 5) Divisor << 0
  --------
  11111111 (-1) NOK ---------------> Quotient = 00000110 (6)
+ 00000101 ( 5) Restore
  --------
  00000100 ( 4) Remainder

In code:

; ------------------------------
; Non-restoring
; IN (edx:eax,ecx:ebx) OUT (edx:eax,ecx:ebx,CF)
uDiv:   test    ecx, ecx
        jnz     .uDiv
        cmp     edx, ebx
        jnb     .uDiv
        div     ebx             ; EDX:EAX / EBX --> EAX Quotient, EDX Remainder
        mov     ebx, edx        ; Remainder to ECX:EBX
        xor     edx, edx        ; Quotient to EDX:EAX
        ret                     ; CF=0
; - - - - - - - - - - - - - - -
; IN (edx:eax,ecx:ebx) OUT (edx:eax,ecx:ebx,CF)
.uDiv:  push    esi edi
        mov     esi, ebx
        or      esi, ecx
        stc
        jz      .NOK            ; (i) Division by 0

        xor     edi, edi
        push    edi edi         ; (1) 64-bit Quotient under construction
        call    .BSR            ; -> ESI ZF
        jz      .NIL            ; (ii) Dividend is 0
        mov     edi, esi        ; Save position highest set bit in Dividend
        xchg    ebx, eax        ; -> ECX:EBX is Dividend, EDX:EAX is Divisor
        xchg    ecx, edx
        call    .BSR            ; -> ESI ZF=0 (because we know Divisor <> 0)
        sub     edi, esi        ; Delta between positions of highest set bits
        jb      .OK             ; (iii) Small Dividend / Big Divisor
        jz      .d              ; No shifting required
        cmp     edi, 32         ; Shift up Divisor so it aligns with Dividend
        jb      .a
        xchg    edx, eax        ; Before EDX was 0
.a:     xchg    ecx, edi
        shld    edx, eax, cl    ; CPU uses CL Mod 32
        shl     eax, cl
        xchg    ecx, edi

        jmp     .d
.OK_:   add     ebx, eax        ; Final restore to obtain Remainder
        adc     ecx, edx
        jmp     .OK

        ALIGN   16
.b:     dec     edi
        js      .OK_            ; We're (back) at the original Divisor
        shr     edx, 1          ; Next try a smaller Divisor (/2)
        rcr     eax, 1
        add     ebx, eax        ; This ADD/ADC replaces the restoring
        adc     ecx, edx        ;  ADD/ADC followed by a further SUB/SBB
        js      .b
        jmp     .e

        ALIGN   16
.c:     dec     edi
        js      .OK             ; We're (back) at the original Divisor
        shr     edx, 1          ; Next try a smaller Divisor (/2)
        rcr     eax, 1
.d:     sub     ebx, eax        ; Try subtracting Divisor from Dividend
        sbb     ecx, edx
        jb      .b              ; Cannot
.e:     bts     [esp], edi      ; -(1)- Add partial quotient
        mov     esi, ebx        ; Is Dividend reduced to zero ?
        or      esi, ecx
        jnz     .c              ; Not yet

.NIL:   xor     ebx, ebx        ; Zero Remainder
        xor     ecx, ecx
.OK:    pop     eax edx         ; (1) EDX:EAX is Quotient, ECX:EBX is Remainder
        clc
.NOK:   pop     edi esi
        ret
; - - - - - - - - - - - - - - -
; IN (edx:eax) OUT (esi,ZF)
.BSR:   xor     esi, esi
        test    edx, edx
        jnz     @f
        bsr     esi, eax        ; -> ESI=[0,31] ZF
        ret
@@:     bsr     esi, edx        ; -> ESI=[0,31] ZF=0
        add     esi, 32         ; -> ESI=[32,63] ZF=0
        ret
; ------------------------------

EDX:EAX 中的 64 位值除以 ECX:EBX 中的 64 位值有符号除法

最简单的方法是写一个wrapper围绕我们上面讨论的无符号除法:

  • 如果输入是负数,我们会将其设为正数,并且我们会记住这样做。
  • 划分negative值 8000'0000'0000'0000h 除 -1 不允许产生positive值 8000'0000'0000'0000h 大于最大有符号整数 7FFF'FFFF'FFFF'FFFFh (.c:).
  • 商的符号是被除数和除数的符号的 XOR,因此两次减 (-) 的结果是加 (+) (.d:).
  • 余数的符号与我们在股息上的符号相同(.e:).
; ------------------------------
; IN (edx:eax,ecx:ebx) OUT (edx:eax,ecx:ebx,CF)
iDiv:   push    esi
        xor     esi, esi
        test    edx, edx        ; Sgn(Num1)
        jns     .a
        neg     edx             ; Abs(Num1)
        neg     eax
        sbb     edx, esi        ; ESI=0
        xor     esi, 3          ; Bit 1 is for Remainder, bit 0 is for Quotient
.a:     test    ecx, ecx        ; Sgn(Num2)
        jns     .b
        neg     ecx             ; Abs(Num2)
        neg     ebx
        sbb     ecx, 0
        xor     esi, 1          ; Bit 0 is for Quotient
.b:     call    uDiv            ; -> EDX:EAX ECX:EBX CF
        jc      .NOK            ; 'Division by zero'
.c:     test    edx, edx
        jns     .d              ; It's not 8000'0000'0000'0000h
        cmp     esi, 11b
        jb      .NOK            ; Signed overflow
.d:     shr     esi, 1          ; Sign for Quotient
        jnc     .e
        neg     edx             ; Neg(Quotient)
        neg     eax
        sbb     edx, 0
.e:     shr     esi, 1          ; Sign for Remainder
        jnc     .OK
        neg     ecx             ; Neg(Remainder)
        neg     ebx
        sbb     ecx, esi        ; ESI=0

.OK:    clc
.NOK:   pop     esi
        ret
; ------------------------------

看看这个转换算法如果您需要显示 EDX:EAX 中的 64 位数字。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在汇编中进行 64 位乘 64 位除法? 的相关文章

  • 如何在 Linux x86_64 上模拟 iret

    我正在编写一个基于 Intel VT 的调试器 由于当 NMI Exiting 1 时 iret 指令在 vmx guest 中的性能发生了变化 所以我应该自己处理vmx主机中的NMI 否则 guest会出现nmi可重入错误 我查了英特尔手
  • ARMv8 A64 汇编中立即值的范围

    我的理解是 ARMv8 A64 汇编中的立即参数可以是 12 位长 如果是这样的话 为什么这行汇编代码是 AND X12 X10 0xFEF 产生此错误 使用 gcc 编译时 Error immediate out of range at
  • 从 exe 文件中获取汇编级代码?

    我当时正在做linux汇编编程 在过去的几天里我已经转而学习windows汇编编程 我在用ml作为我的汇编器和golink作为我的链接器 我有我的汇编代码并已获得我的exe从中 现在我需要取回它的十六进制 xff xab x55等等 在li
  • 如何在 Debian 上编译 DOS 程序?

    在我的汇编语言课程中 我们使用 DPMI 编写 DOS 程序 不幸的是 我无法一直使用 32 位 Windows 机器 我在我使用的几乎每台计算机上都安装了 Debian 虚拟机 我已经安装了 DOSBox 和 DOSEMU 有什么办法可以
  • 具有非常大的数字的除法

    我只是想知道在处理大数字时有哪些不同的除法策略 我所说的大数字是指 50 位数字 例如 9237639100273856744937827364095876289200667937278 82637448262718273966299344
  • 使用 NEON 优化 Cortex-A8 颜色转换

    我目前正在执行颜色转换例程 以便从 YUY2 转换为 NV12 我有一个相当快的函数 但没有我预期的那么快 主要是由于缓存未命中 void convert hd uint8 t orig uint8 t result uint32 t wi
  • AVX-512 指令编码 - {er} 含义

    在 Intel x86 指令集参考中 有许多 AVX 512 指令在指令中具有可选的 er 例如 VADDPD 的一种形式定义为 EVEX NDS 512 66 0F W1 58 r VADDPD zmm1 k1 z zmm2 zmm3 m
  • linux x86 汇编语言 sys_read 调用的第一个参数应为 0 (stdin)

    我正在编写一个简单的汇编程序来从标准输入读取 如 scanf 这是我的代码 section bss num resb 5 section txt global start start mov eax 3 sys read mov ebx 0
  • X86 预取优化:“计算 goto”线程代码

    我有一个相当重要的问题 我的计算图有循环和多个 计算路径 我没有制作一个调度程序循环 其中每个顶点将被一一调用 而是将所有预先分配的 框架对象 放置在堆中 代码 数据 这有点类似于线程代码 甚至更好 CPS 只是在堆中跳转 执行代码 每个代
  • 为什么 FMA _mm256_fmadd_pd() 内在函数有 3 个 asm 助记符:“vfmadd132pd”、“231”和“213”?

    有人可以向我解释一下为什么融合乘法累加指令有 3 种变体 vfmadd132pd vfmadd231pd and vfmadd213pd 而只有一个 C 内在函数 mm256 fmadd pd 为了简单起见 在 AT T 语法中 有什么区别
  • 在 x86 程序集中存储大量布尔值的最佳方法是什么?

    最近我一直在处理充满布尔值的大型数组 目前 我将它们存储在 bss部分有一个 space指令 它允许我创建字节数组 但是 由于我只需要存储布尔值 因此我希望从数组中逐位读取和写入数据 目前 我能想到的最好方法是有一个 space指令所需存储
  • 高效memcspn

    有谁知道 memcspn 函数的有效实现吗 它的行为应该类似于 strcspn 但在内存缓冲区中查找跨度 而不是在以 null 结尾的字符串中查找跨度 目标编译器是 VisualC 谢谢 卢卡 一种近乎最佳的实现 size t memcsp
  • 32位PPC rlwinm指令

    我在理解上有点困难rlwinmPPC 汇编指令 旋转左字立即然后与掩码 我正在尝试反转函数的这一部分 rlwinm r3 r3 0 28 28 我已经知道什么了r3 is r3在本例中是一个 4 字节整数 但我不确定这条指令到底是什么rlw
  • gdb查找行号的内存地址

    假设我已将 gdb 附加到一个进程 并且在其内存布局中有一个文件和行号 我想要其内存地址 如何获取文件x中第n行的内存地址 这是在 Linux x86 上 gdb info line test c 56 Line 56 of test c
  • NASM 中的 equ 和 db 有什么区别?

    len equ 2 len db 2 它们是否相同 产生可以用来代替的标签2 如果不是 那么每种申报表的优点或缺点是什么 它们可以互换使用吗 第一个是equate 与 C 类似 define len 2 因为它实际上并没有在最终代码中分配任
  • 使用按位运算符相乘

    我想知道如何使用按位运算符将一系列二进制位相乘 但是 我有兴趣这样做来查找二进制值的十进制小数值 这是我正在尝试做的一个例子 假设 1010010 我想使用每个单独的位 以便将其计算为 1 2 1 0 2 2 1 2 3 0 2 4 虽然我
  • 何时可以重用avx指令中的源寄存器

    在 avx 指令中用作源的寄存器何时可以在指令开始处理后重用 例如 我想使用vgatherdps该指令消耗两个 ymm 寄存器 其中之一是位移索引 我意识到vgatherdps由于数据的局部性较差 因此需要花费大量时间来收集 位移索引寄存器
  • movzbl(%rdi, %rcx, 1), %ecx 在 x86-64 汇编中意味着什么?

    我想我明白 movzbl rdi rcx 1 ecx 意思是 将零扩展字节移至长整型 并表示将 ecx 扩展为 32 位 但我不完全确定语法 rdi rcx 1 指的是什么 我在某处看到该语法指的是 Base Index Scale 但我找
  • 英特尔的最后分支记录功能是英特尔处理器独有的吗?

    最后分支记录是指存储与最近执行的分支相关的源地址和目标地址的寄存器对 MSR 的集合 它们受英特尔酷睿 2 英特尔至强和英特尔凌动处理器系列的支持 http css csail mit edu 6 858 2012 readings ia3
  • Grub 和进入实模式(低级汇编语言编程)

    我一直在开发一个玩具操作系统 并一直使用 grub 作为我的引导加载程序 最近尝试使用 VGA 时 我发现无法使用硬件中断 我发现这是因为我被 grub 置于保护模式 有人知道如何在不删除 grub 的情况下回到实模式吗 如果您使用 GRU

随机推荐

  • 在asp.net MVC中DropDownList设置所选项目

    我注意到在我看来是 ASP NET MVC 中的一个错误 或者只是我做错了什么 我目前使用的是 1 0 所以也许这个问题将在 2 0 版本中得到解决 但无论如何 我们开始吧 当我的视图模型有一个与下拉列表声明的 id 名称相同的属性时 所选
  • 强制 R 将科学记数法写为带上标的 n.nn x 10^-n

    假设我有两个花车 a lt 8 9384920e 24 b lt 0 00293892837 我想在图表上以 10 基科学记数法四舍五入到两位小数显示它们中的任何一个 可能使用paste 但在 10 之后采用上标格式 8 94 x 10 2
  • 如果文件是在过去一小时内创建的,则从 FTP 下载文件

    我需要从 FTP 上的特定文件夹下载文件 但仅限于创建时间在过去一小时内的文件 所以基本上我需要列出该文件夹中的所有文件 然后仅下载时间戳与执行时间相差超过一小时的文件 关于如何解析 FTP 上文件的时间戳有什么想法吗 我无法使用任何第 3
  • 使用 vanilla Javascript 查找具有部分属性的 DOM 元素

    假设我有一个网站 我想使用循环遍历其 DOM 元素的脚本 并指出这些元素的属性包含指定文本的一部分 我成功创建了一个简单的循环 可以找到 DOM 元素的每个所需属性并从中创建数组 现在我想将数组属性值与其所属的 DOM 元素配对 并且还能够
  • Android 锁定全屏

    Android 可以锁定全屏吗 基本上隐藏吐司 隐藏主页 后退 开关 隐藏通知栏 使其从底部或顶部滑动不起作用 致力于一个将从中受益匪浅的想法 我知道这样做很不好 但它针对的是非常年幼的孩子 他们随机点击 拖动 偶尔会意外地将手机语言更改为
  • 如何停止与 canvas imageData 的 alpha 预乘?

    有没有办法停止画布数据的 Alpha 通道的预乘 或者解决方法 我想生成一个图像 在本例中是一些随机的 rgba 值 并将画布保存为图像 在第二步中 我想使用 imageData 将原始图像与生成的图像进行比较 但是由于生成图像中 rgba
  • 何时在 GUI 应用程序中调用 thread.join

    import wx import json import queue from collections import namedtuple import threading class MyDialog wx Frame def init
  • Sublime Text 构建:找不到指定的文件

    我已经通过 Package Control 安装了 CoffeeScript 插件 当我尝试构建 test coffee 时 它 给了我这个 Error 2 The system cannot find the file specified
  • 在 XZ 平面上拖动对象

    我正在开发一个增强现实应用程序 我希望能够在空间中拖动一个对象 我在 SO 中找到的解决方案存在问题 建议使用projectPoint unprojectPoint 是它们沿着XY plane 我试图使用屏幕上的手指移动作为偏移x and
  • npm run script 导致 Windows Script Host 错误

    我尝试使用 npm 来缩小 javascript 这是我的 package json name name1 version 1 0 0 description scripts minifyjs minifyJs minifycss mini
  • 如何阻止 PHP 中的无限递归函数耗尽所有可用内存并最终导致笔记本电脑崩溃?

    我这里有一个简单的无限递归代码
  • 使用 TokenRegex 以所需格式获取输出

    我正在使用 TokensRegex 进行基于规则的实体提取 它运行良好 但我无法以所需的格式获得输出 以下代码片段为我提供了以下句子的输出 本月早些时候 特朗普针对丰田 威胁要对其实施制裁 如果世界上最大的汽车制造商生产卡罗拉 它将收取高额
  • bash 中的浮点除法

    我正在尝试将用户输入的任何数字转换为小数点后两位 例如 What is the total cost in cents 2345 output 23 45 这是我到目前为止的代码 percentage 20 cannot change nu
  • 从 WPF Web 浏览器静默打印 HTML

    我必须从 WPF 中的 WebBrowser 静默打印 HTML 文档 我已经通过该代码不默默地完成了它 mshtml IHTMLDocument2 doc WebBrowser1 Document as mshtml IHTMLDocum
  • 如何将固定功能材质和光照传递给片段着色器?

    我正在向 OpenGL 2 1 GLSL 1 2 应用程序添加顶点和片段着色器 顶点着色器 version 120 void main void gl Position ftransform gl FrontColor gl Color 片
  • 如何为加载项设置默认浏览器

    我正在尝试为我正在使用的 chrome 插件设置默认浏览器 但默认情况下它始终使用 IE 我该如何改变这个 我假设您正在谈论您的加载项生成新的浏览器窗口 弹出窗口的场景 在 Windows 上 这始终是 Internet Explorer
  • HTML 验证和 ASP.NET Webforms

    我正在尝试 HTML 内置验证属性 遇到的第一个困难是验证属性在表单上下文中工作 IE 如果你想验证两个独立的输入 那么你应该将它们放在两个不同的输入中
  • 是否可以覆盖 Local.config 文件中的 appSettings 和 connectionStrings?

    我们目前覆盖appSettings来自每个开发人员的 Local config 文件中的 web config 但是 我们还需要覆盖连接字符串 因此我们可以访问计算机上的本地副本 而 web config 可能会引用生产服务器 我知道您可以
  • Python:将嵌套列表作为输入?

    处理以下问题的最佳方法是什么 我想让用户输入一个嵌套列表 如下所示 grid input Enter grid 用户将输入如下所示的网格 X O X O X X 问题是我将此输入传递给一个期望输入是嵌套列表的函数 当获取输入网格时 它将是一
  • 如何在汇编中进行 64 位乘 64 位除法?

    如何在 x86 汇编中实现 64 位乘 64 位除法 我已经启用了扩展寄存器 386指示 EDX EAX 中的 64 位值除以 ECX EBX 中的 64 位值的无符号除法 在 32 位 x86 CPU 上 the div操作说明可以将 E