如何在X86组装中分配两个未签名的长64位值,然后将商和剩余的返回到C程序

发布于 2025-01-25 11:25:34 字数 425 浏览 1 评论 0原文

在单独的C程序中,我已将4个参数传递给X86 ASM程序。

  1. 股息
  2. 除数
  3. 商指针
  4. 剩余指针

股息= 0xa
除数= 0x3

,即10/3。

商应为3,其余应为1。

但是,我的商正在返回C2,其余的是返回7FFFFFFF396F687。这两者都远远与我应该得到的相距遥远。我已经尝试调试我的ASM代码,但我无法弄清楚问题是什么。

这就是我到目前为止的。我是初学者。

global divide64u
divide64u:
push rbp
mov rbp, rsp
mov rdx, rdi
mov rax, rsi
xor rdx, rdx 
div r10
divide64uDone:
pop rbp
ret

In a separate C program, I have passed 4 parameters to an x86 ASM program.

  1. dividend
  2. divisor
  3. Quotient pointer
  4. Remainder pointer

dividend = 0xA
divisor = 0x3

Which is 10/3.

The quotient should be 3 and the remainder should be 1.

However, my quotient is returning c2 and my remainder is returning 7ffff396f687. Both of which are extremely far off of what i should be getting. I've tried debugging my ASM code and I can't figure out what the problem is.

This is what I have so far. I'm a beginner at this.

global divide64u
divide64u:
push rbp
mov rbp, rsp
mov rdx, rdi
mov rax, rsi
xor rdx, rdx 
div r10
divide64uDone:
pop rbp
ret

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

药祭#氼 2025-02-01 11:25:34

对于X86_64,根据ABI,ARGS全部传递在寄存器中。

因此,无需按/pop rbp/rsp

实际上可以在C中进行编码,并且编译器Optimizer将生成最有效的代码:

typedef unsigned long long u64;

void
davdiv(u64 div,u64 dvr,u64 *quot,u64 *rem)
{

    __asm__ (
        "\tdiv %[dvr]\n"
    :   [quot] "=a" (*quot),
        [rem] "=d" (*rem)
    :   [div] "a" (div),
        [dvr] "r" (dvr),
        "d" (0));
}

void
mydiv(u64 div,u64 dvr,u64 *quot,u64 *rem)
{

    __asm__ __volatile__(
        "\txor  %%edx,%%edx\n"
        "\tmov  %[div],%%rax\n"
        "\tdiv  %[dvr]\n"
        "\tmov  %%rax,%[quot]\n"
        "\tmov  %%rdx,%[rem]\n"
    :   [quot] "=m" (*quot),
        [rem] "=m" (*rem)
    :   [div] "r" (div),
        [dvr] "r" (dvr)
    :   "rax", "rdx");
}

void
cpldiv(u64 div,u64 dvr,u64 *quot,u64 *rem)
{

    *quot = div / dvr;
    *rem = div % dvr;
}

u64
cplretA(u64 div,u64 dvr,u64 *rem)
{
    u64 quot;

    quot = div / dvr;
    *rem = div % dvr;

    return quot;
}

u64
cplretB(u64 div,u64 dvr,u64 *quot)
{
    u64 rem;

    *quot = div / dvr;
    rem = div % dvr;

    return rem;
}

这是上述用-O2汇编的拆卸代码


div2.o:     file format elf64-x86-64

Disassembly of section .text:

0000000000000000 <davdiv>:
   0:   49 89 d0                mov    %rdx,%r8
   3:   48 89 f8                mov    %rdi,%rax
   6:   31 d2                   xor    %edx,%edx
   8:   48 f7 f6                div    %rsi
   b:   49 89 00                mov    %rax,(%r8)
   e:   48 89 11                mov    %rdx,(%rcx)
  11:   c3                      retq
  12:   66 66 2e 0f 1f 84 00    data16 nopw %cs:0x0(%rax,%rax,1)
  19:   00 00 00 00
  1d:   0f 1f 00                nopl   (%rax)

0000000000000020 <mydiv>:
  20:   49 89 d0                mov    %rdx,%r8
  23:   31 d2                   xor    %edx,%edx
  25:   48 89 f8                mov    %rdi,%rax
  28:   48 f7 f6                div    %rsi
  2b:   49 89 00                mov    %rax,(%r8)
  2e:   48 89 11                mov    %rdx,(%rcx)
  31:   c3                      retq
  32:   66 66 2e 0f 1f 84 00    data16 nopw %cs:0x0(%rax,%rax,1)
  39:   00 00 00 00
  3d:   0f 1f 00                nopl   (%rax)

0000000000000040 <cpldiv>:
  40:   48 89 f8                mov    %rdi,%rax
  43:   48 89 d7                mov    %rdx,%rdi
  46:   31 d2                   xor    %edx,%edx
  48:   48 f7 f6                div    %rsi
  4b:   48 89 07                mov    %rax,(%rdi)
  4e:   48 89 11                mov    %rdx,(%rcx)
  51:   c3                      retq
  52:   66 66 2e 0f 1f 84 00    data16 nopw %cs:0x0(%rax,%rax,1)
  59:   00 00 00 00
  5d:   0f 1f 00                nopl   (%rax)

0000000000000060 <cplretA>:
  60:   48 89 d1                mov    %rdx,%rcx
  63:   48 89 f8                mov    %rdi,%rax
  66:   31 d2                   xor    %edx,%edx
  68:   48 f7 f6                div    %rsi
  6b:   48 89 11                mov    %rdx,(%rcx)
  6e:   c3                      retq
  6f:   90                      nop

0000000000000070 <cplretB>:
  70:   48 89 d1                mov    %rdx,%rcx
  73:   48 89 f8                mov    %rdi,%rax
  76:   31 d2                   xor    %edx,%edx
  78:   48 f7 f6                div    %rsi
  7b:   48 89 01                mov    %rax,(%rcx)
  7e:   48 89 d0                mov    %rdx,%rax
  81:   c3                      retq

For x86_64, the args are all passed in registers, per the ABI.

So, no need to push/pop rbp/rsp

You can actually code this in C and the compiler optimizer will generate the most efficient code:

typedef unsigned long long u64;

void
davdiv(u64 div,u64 dvr,u64 *quot,u64 *rem)
{

    __asm__ (
        "\tdiv %[dvr]\n"
    :   [quot] "=a" (*quot),
        [rem] "=d" (*rem)
    :   [div] "a" (div),
        [dvr] "r" (dvr),
        "d" (0));
}

void
mydiv(u64 div,u64 dvr,u64 *quot,u64 *rem)
{

    __asm__ __volatile__(
        "\txor  %%edx,%%edx\n"
        "\tmov  %[div],%%rax\n"
        "\tdiv  %[dvr]\n"
        "\tmov  %%rax,%[quot]\n"
        "\tmov  %%rdx,%[rem]\n"
    :   [quot] "=m" (*quot),
        [rem] "=m" (*rem)
    :   [div] "r" (div),
        [dvr] "r" (dvr)
    :   "rax", "rdx");
}

void
cpldiv(u64 div,u64 dvr,u64 *quot,u64 *rem)
{

    *quot = div / dvr;
    *rem = div % dvr;
}

u64
cplretA(u64 div,u64 dvr,u64 *rem)
{
    u64 quot;

    quot = div / dvr;
    *rem = div % dvr;

    return quot;
}

u64
cplretB(u64 div,u64 dvr,u64 *quot)
{
    u64 rem;

    *quot = div / dvr;
    rem = div % dvr;

    return rem;
}

Here is the disassembly of the above compiled with -O2:


div2.o:     file format elf64-x86-64

Disassembly of section .text:

0000000000000000 <davdiv>:
   0:   49 89 d0                mov    %rdx,%r8
   3:   48 89 f8                mov    %rdi,%rax
   6:   31 d2                   xor    %edx,%edx
   8:   48 f7 f6                div    %rsi
   b:   49 89 00                mov    %rax,(%r8)
   e:   48 89 11                mov    %rdx,(%rcx)
  11:   c3                      retq
  12:   66 66 2e 0f 1f 84 00    data16 nopw %cs:0x0(%rax,%rax,1)
  19:   00 00 00 00
  1d:   0f 1f 00                nopl   (%rax)

0000000000000020 <mydiv>:
  20:   49 89 d0                mov    %rdx,%r8
  23:   31 d2                   xor    %edx,%edx
  25:   48 89 f8                mov    %rdi,%rax
  28:   48 f7 f6                div    %rsi
  2b:   49 89 00                mov    %rax,(%r8)
  2e:   48 89 11                mov    %rdx,(%rcx)
  31:   c3                      retq
  32:   66 66 2e 0f 1f 84 00    data16 nopw %cs:0x0(%rax,%rax,1)
  39:   00 00 00 00
  3d:   0f 1f 00                nopl   (%rax)

0000000000000040 <cpldiv>:
  40:   48 89 f8                mov    %rdi,%rax
  43:   48 89 d7                mov    %rdx,%rdi
  46:   31 d2                   xor    %edx,%edx
  48:   48 f7 f6                div    %rsi
  4b:   48 89 07                mov    %rax,(%rdi)
  4e:   48 89 11                mov    %rdx,(%rcx)
  51:   c3                      retq
  52:   66 66 2e 0f 1f 84 00    data16 nopw %cs:0x0(%rax,%rax,1)
  59:   00 00 00 00
  5d:   0f 1f 00                nopl   (%rax)

0000000000000060 <cplretA>:
  60:   48 89 d1                mov    %rdx,%rcx
  63:   48 89 f8                mov    %rdi,%rax
  66:   31 d2                   xor    %edx,%edx
  68:   48 f7 f6                div    %rsi
  6b:   48 89 11                mov    %rdx,(%rcx)
  6e:   c3                      retq
  6f:   90                      nop

0000000000000070 <cplretB>:
  70:   48 89 d1                mov    %rdx,%rcx
  73:   48 89 f8                mov    %rdi,%rax
  76:   31 d2                   xor    %edx,%edx
  78:   48 f7 f6                div    %rsi
  7b:   48 89 01                mov    %rax,(%rcx)
  7e:   48 89 d0                mov    %rdx,%rax
  81:   c3                      retq
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文