相关疑难解决方法(0)

为什么我不能直接将字节移动到64位寄存器?

为什么我不能直接将一个字节从内存移动到Intel x86-64汇编中的64位寄存器?

例如,这段代码:

extern printf

global main

segment .text

main:
    enter   2, 0

    mov     byte [rbp - 1], 'A'
    mov     byte [rbp - 2], 'B'

    mov     r12, [rbp - 1]
    mov     r13, [rbp - 2]             

    xor     rax, rax           
    mov     rdi, Format                                                                                             
    mov     rsi, r12                                                                                                
    mov     rdx, r13                                                                                                
    call    printf                                                                                                  

    leave                                                                                                           
    ret                                                                                                             

segment .data                                                                                                       
Format:     db "%d %d", 10, 0
Run Code Online (Sandbox Code Playgroud)

打印:

65 16706
Run Code Online (Sandbox Code Playgroud)

我需要将移动字节更改为寄存器r12和r13,以使代码正常工作:

xor     rax, rax
mov     al, byte [rbp - 1]
mov     r12, rax
xor     rax, rax
mov     al, …
Run Code Online (Sandbox Code Playgroud)

assembly x86-64

4
推荐指数
1
解决办法
4335
查看次数

"添加esp,0FFFFFFF8h"的序幕

我的MASM上有点生疏,所以我真的不记得在这里做什么(如果有什么需要做的话).我有一个MASM(X86)例程,如下所示.它有两个局部变量,共占用5个字节:

MSC_ASM_GenerateBlock PROC buffer:DWORD,bsize:DWORD,safety:DWORD
  LOCAL val:DWORD, rc:BYTE  ;; local variables
  MWSIZE EQU 4              ;; machine word size

  .WHILE bsize >= MWSIZE && safety > 0
     ;; RDRAND is not available prior to VS2012. Just emit
     ;;   the byte codes using DB. This is `rdrand eax`.
     DB 0Fh, 0C7h, 0F0h
     setc rc
     ...
  .ENDW
  ...
MSC_ASM_GenerateBlock ENDP
Run Code Online (Sandbox Code Playgroud)

当我检查拆卸时,我看到:

> dumpbin.exe /DISASM rdrand-x86.obj
Dump of file rdrand-x86.obj

_MSC_ASM_GenerateBlock:
  00000000: 55                 push        ebp
  00000001: 8B EC              mov         ebp,esp
  00000003: 83 C4 F8           add …
Run Code Online (Sandbox Code Playgroud)

x86 assembly masm integer-overflow stack-pointer

3
推荐指数
1
解决办法
799
查看次数

yasm movsx、movsxd 操作数 2 的大小无效

我正在尝试使用 yasm 汇编下面的代码。我在 yasm 报告错误“错误:操作数 2 的大小无效”的地方添加了“此处”注释。为什么会发生这个错误?

segment .data
    a db 25
    b dw 0xffff
    c dd 3456
    d dq -14

segment .bss
    res resq 1

segment .text
    global _start

_start:
    movsx rax, [a] ; here
    movsx rbx, [b] ; here 
    movsxd rcx, [c] ; here
    mov rdx, [d]
    add rcx, rdx
    add rbx, rcx
    add rax, rbx
    mov [res], rax
    ret
Run Code Online (Sandbox Code Playgroud)

assembly x86-64 nasm yasm

3
推荐指数
1
解决办法
1986
查看次数

ASM x86_64 AVX:xmm和ymm记录差异

xmmymm寄存器有什么区别?我以为xmm是SSE,ymm是AVX,但是我写了一些代码:

vmovups     ymm1, [r9]      
vcvtss2si   rcx, ymm1
Run Code Online (Sandbox Code Playgroud)

它给了我:

error: invalid combination of opcode and operands
Run Code Online (Sandbox Code Playgroud)

关于这条线:

vcvtss2si   rcx, ymm1
Run Code Online (Sandbox Code Playgroud)

所以我写道:

vcvtss2si   rcx, xmm1
Run Code Online (Sandbox Code Playgroud)

它按预期工作。ymm1向量的第一个值转换为整数,现在位于中rcx

这是什么一回事呢?ymm1xmm1相同的寄存器?

assembly x86-64 nasm avx

3
推荐指数
2
解决办法
3219
查看次数

如何将数字转换为十六进制?

给定寄存器中的数字(二进制​​整数),如何将其转换为十六进制ASCII数字字符串?

数字可以存储在存储器中或即时打印,但存储在存储器中并一次打印通常更有效.(您可以修改存储的循环,而不是一次打印一个循环.)

我们能否有效地处理与SIMD并行的所有半字节?(SSE2或更高版本?)

x86 assembly hex simd avx512

3
推荐指数
1
解决办法
342
查看次数

为什么添加 xorps 指令使这个函数使用 cvtsi2ss 并添加 ~5x 快?

我正在使用 Google Benchmark 优化一个函数,并遇到了我的代码在某些情况下意外变慢的情况。我开始试验它,查看编译后的程序集,并最终想出了一个最小的测试用例来展示这个问题。这是我想出的展示这种放缓的程序集:

    .text
test:
    #xorps  %xmm0, %xmm0
    cvtsi2ss    %edi, %xmm0
    addss   %xmm0, %xmm0
    addss   %xmm0, %xmm0
    addss   %xmm0, %xmm0
    addss   %xmm0, %xmm0
    addss   %xmm0, %xmm0
    addss   %xmm0, %xmm0
    addss   %xmm0, %xmm0
    addss   %xmm0, %xmm0
    retq
    .global test
Run Code Online (Sandbox Code Playgroud)

此函数遵循 GCC/Clang 的 x86-64 函数声明调用约定extern "C" float test(int);注意注释掉的xorps指令。取消注释此指令可显着提高函数的性能。用我的机器有i7-8700K,谷歌基准测试显示的功能测试它,而不xorps指令需要8.54ns(CPU),而功能xorps指令需要1.48ns。我已经在具有不同操作系统、处理器、处理器世代和不同处理器制造商(英特尔和 AMD)的多台计算机上对此进行了测试,它们都表现出类似的性能差异。重复addss指令使减速更加明显(在某种程度上),并且这种减速仍然使用此处的其他指令(例如mulss)或什至混合指令发生,只要它们都%xmm0以某种方式依赖于值。值得指出的是,只调用xorps 每个函数调用会导致性能提升。使用循环对性能进行采样(如 Google Benchmark 所做的那样)和xorps循环外的调用仍然显示出较慢的性能。

由于这是一种专门添加指令可以提高性能的情况,因此这似乎是由 CPU 中的一些非常低级的东西引起的。由于它发生在各种 CPU …

sse x86-64 cpu-architecture clang microbenchmark

3
推荐指数
1
解决办法
167
查看次数

为什么汇编代码在添加到总和之前将值从 %edx 复制到 %rcx?

使用 x86-64 gcc -Og -std=gnu99 -xc 编译。

.L3 ( addl (%rdi,%rcx,4), %eax)的第二行中,为什么不直接%edx在加和时使用寄存器?

addl (%rdi,%edx,4), %eax

int sum_arr(int arr[], int nelems) {
  int sum = 0;
  for (int i = 0; i < nelems; i++) {
    sum += arr[i];
  }
  return sum;
}

sum_arr:
        movl    $0, %edx
        movl    $0, %eax
        jmp     .L2
.L3:
        movslq  %edx, %rcx
        addl    (%rdi,%rcx,4), %eax
        addl    $1, %edx
.L2:
        cmpl    %esi, %edx
        jl      .L3
        rep ret
Run Code Online (Sandbox Code Playgroud)

c arrays assembly gcc x86-64

3
推荐指数
1
解决办法
90
查看次数

在 VBA 中直接执行汇编代码 - 仅在 Excel 中失败

我有一些 VBA 代码,用于将 COM vtable 中的函数指针之一与汇编代码的 NO-OP 位交换。它在 twinBASIC 中工作,这是一个独立的 VBA 环境,所以我知道我已经非常接近了,但是在 Excel 中它崩溃了。

这是 minrepro,可以在 tB 中运行,理论上不能在 Excel VBA 中运行。

Class DummyThing
    Sub DoNothing()
    End Sub
End Class

Module VBA
    Private Const MEM_COMMIT As Long = &H1000
    Private Const MEM_RESERVE As Long = &H2000
    Private Const PAGE_EXECUTE_READWRITE  As Long = &H40

    Declare PtrSafe Function VirtualAlloc Lib "kernel32" ( _
            ByVal lpAddress As LongPtr, _
            ByVal dwSize As Long, _
            ByVal flAllocationType As Long, _
            ByVal flProtect As …
Run Code Online (Sandbox Code Playgroud)

com assembly vba x86-64 shellcode

3
推荐指数
1
解决办法
202
查看次数

了解 libc.a 中的简单 Linux 系统调用

我正在使用glibc-2.13-1运行64 位 Debian 4.7.2-5 Linux系统。当我在搜索一些函数调用的汇编代码时,我遇到了这个:libc.a

file format elf64-x86-64

Disassembly of section .text:

0000000000000000 <sync>:
   0:   b9 a2 00 00 00        mov    eax,0xa2
   5:   0f 05                 syscall
   7:   48 3d 01 f0 ff ff     cmp    rax,0xfffffffffffff001
   d:   0f 83 00 00 00 00     jae    13 <sync+0x13>
  13:   c3                    ret
Run Code Online (Sandbox Code Playgroud)

我对这是做什么感到有点困惑。如果这是一台 64 位机器(系统调用如何知道要进行什么系统调用),有什么意义mov eax,0xa2以及为什么不使用rax寄存器?简而言之:这 5 行代码做了什么?

linux assembly x86-64 system-calls

2
推荐指数
1
解决办法
645
查看次数

无法理解寄存器和变量之间的汇编mov指令

我在Linux 64位上使用NASM汇编程序。我无法理解某些带有变量和寄存器的东西。我创建一个名为“ msg”的变量:

 msg db "hello, world"  
Run Code Online (Sandbox Code Playgroud)

现在,当我想写入标准输出时,我将其移动msgrsi寄存器,但是我不mov按位理解指令……rsi寄存器由64位组成,而msg变量具有12个符号,每个符号8位,这意味着msg变量的大小为12 * 8bit,显然大于64位。

因此,如何使这样的指令成为可能:
mov rsi, msg 而不溢出分配给rsi的内存。

还是rsi寄存器包含字符串的第一个符号的存储位置,并且在写入1个符号后将其更改为下一个符号的存储位置?

抱歉,如果我写的是完全废话,我是组装的新手,我暂时无法掌握它。

string x86 assembly nasm

2
推荐指数
1
解决办法
776
查看次数