标签: x86-64

有没有办法使用 C++ 检查 BIOS 上是否启用了虚拟化?

我正在尝试检查是否以编程方式启用虚拟化(AMD-V 或 Intel VT)。我知道 bash命令可以为您提供此信息,但我正在尝试在 C++ 中实现此目的。

就这一点而言,我试图避免使用它std::system来执行 shell 代码,因为该解决方案非常糟糕且不是最佳的。提前致谢!

c++ virtualization x86-64

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

int32_t 和 int16_t 之间的 sse4 压缩和(符号扩展至 int32_t)

我有以下代码片段(可以在此处找到要点),其中我尝试对 4 个 int32_t 负值和 4 个 int16_t 值(将符号扩展为 int32_t)之间进行求和。

    extern  exit

    global _start

    section .data

a:     dd -76, -84, -84, -132
b:     dw 406, 406, 406, 406
    
    section .text
_start:
    movdqa xmm0, [a]
    pmovsxwd xmm2, [b]
    paddq xmm0, xmm2
    ;Expected: 330, 322, 322, 274
    ;Results:  330, 323, 322, 275
    call exit
Run Code Online (Sandbox Code Playgroud)

然而,当通过我的调试器时,我无法理解为什么输出结果与预期结果不同。任何想法 ?

linux sse x86-64 intel

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

在 C 函数调用之前,以任何方式(跨编译器、平台、libc 实现等)PUSH 内联汇编中的额外参数是否安全或可移植?

我写了一个函数来漂亮地打印一个数独,当然这个模式可以由一些循环生成,但我不想经历麻烦,所以这就是我想出的(前 5 个格式说明符只是参数) printf 本身被压入堆栈,并且在回车后将被覆盖)。

\n

虽然“它可以在我的机器上运行”,但我想知道这是否可以或可以移植到跨架构、编译器、libc 实现等工作?

\n

当然,根据目标平台,汇编代码可能需要进行一些调整,并且 printf 推送的参数数量取决于当前的 libc 实现。

\n
#define PUSH(x) asm volatile ("push %0" : : "m"(x) :)\n#define POP() asm volatile ("pop %%rax" : : : "rax")\n\nvoid print(void) {\n    for (uint8_t i = 1; i <= (9 * 9); ++i) {\n        PUSH(sudoku[(9 * 9) - i]);\n    }\n\n    printf("%hhd%hhd%hhd%hhd%hhd\\r\xe2\x95\x94\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa6\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa6\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x97\\n"\n           "\xe2\x95\x91 %hhd  %hhd  %hhd \xe2\x95\x91 %hhd  %hhd  %hhd \xe2\x95\x91 %hhd  %hhd  %hhd \xe2\x95\x91\\n"\n           "\xe2\x95\x91 %hhd  %hhd  %hhd \xe2\x95\x91 %hhd  %hhd  %hhd \xe2\x95\x91 %hhd  %hhd  %hhd …
Run Code Online (Sandbox Code Playgroud)

c assembly gcc x86-64 inline-assembly

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

对于 gcc 编译器,当您在没有任何标志的情况下与 -O2 进行编译时,gcc 的目标是什么 x86-64 指令集?

对于 x86-64,有许多指令集可以加速代码执行。以下是 gcc wiki https://gcc.gnu.org/wiki/FunctionMultiVersioning的列表:

  • 多媒体MX
  • 上证所
  • 上证2
  • SSE3
  • SSSE3
  • SSE4.1
  • SSE4.2
  • POPCNT
  • AVX
  • AVX2

对于 gcc 编译器,当您在没有任何标志的情况下编译时,gcc 的目标是什么 x86-64 指令集-O2

为了简单起见,我们只说问题是关于 gcc 版本 12(最新的主要版本)。但我想知道我需要做什么 gcc 命令开关/选项,以便我可以看到我的 gcc 版本的功能。

我认为 gcc 选择了“可移植”的东西,所以这可能意味着速度很慢。但这只是我的假设......我想知道这是否意味着像SSE4.2或没有?

gcc x86-64 simd compiler-optimization

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

为什么 int&amp; 作为函数参数使用 QWORD(8 字节)内存,而 int 参数使用 DWORD

在下面的代码中,

int firstFunction(int& refParam)
{
    std::cout << "Type of refParam is: " << typeid(refParam).name() << '\n';
    return refParam;
}

int secondFunction(int param)
{
    std::cout << "Type of param is: " << typeid(param).name() << '\n';
    return param;
}

int main()
{
    int firstVar{ 1 };
    int secondVar{ firstFunction(firstVar) };
    int thirdVar{ secondFunction(firstVar) };
}
Run Code Online (Sandbox Code Playgroud)

控制台输出是

int
int
Run Code Online (Sandbox Code Playgroud)

当我检查Godbolt 链接中的汇编代码时。

firstFunction(int&):
        push    rbp
        mov     rbp, rsp
        mov     QWORD PTR [rbp-8], rdi
        mov     rax, QWORD PTR [rbp-8]
        mov     eax, DWORD PTR [rax] …
Run Code Online (Sandbox Code Playgroud)

c++ assembly gcc reference x86-64

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

MOV r/m32、imm32 和 MOV r32、imm32 之间的操作码差异

这些是MOV来自Intel\xc2\xae 64 和 IA-32 架构软件开发人员手册的指令操作码:

\n

B8+ rd id MOV r32, imm32 OI Valid Valid Move imm32 to r32

\n

C7 /0 id MOV r/m32, imm32 MI Valid Valid Move imm32 to r/m32

\n

我拆解如下:

\n
0:  b8 44 33 22 11          mov    eax, 0x11223344\n
Run Code Online (Sandbox Code Playgroud)\n
0:  67 c7 00 44 33 22 11    mov    DWORD PTR[eax], 0x11223344\n
Run Code Online (Sandbox Code Playgroud)\n

我想问的问题是:

\n
    \n
  • 为什么C7操作码是寄存器/内存(r/m32, imm32)而不是仅内存(m32, imm32)?

    \n
  • \n
  • 是否有任何时候我们使用 …

assembly x86-64 machine-code opcode instruction-encoding

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

使用未优化的 C (GCC) 固定大小缓冲区的 x86-32 和 x64 汇编堆栈分配的差异

进行一些基本的反汇编,并注意到由于某种原因,缓冲区被给予了额外的缓冲区空间,尽管我在教程中看到的内容使用相同的代码,但仅给出了正确的(500)个字符长度。为什么是这样?

我的代码:

#include <stdio.h>
#include <string.h>

int main (int argc, char** argv){
    char buffer[500];
    strcpy(buffer, argv[1]);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

用GCC编译,反汇编代码为:

   0x0000000000001139 <+0>:     push   %rbp
   0x000000000000113a <+1>:     mov    %rsp,%rbp
   0x000000000000113d <+4>:     sub    $0x210,%rsp
   0x0000000000001144 <+11>:    mov    %edi,-0x204(%rbp)
   0x000000000000114a <+17>:    mov    %rsi,-0x210(%rbp)
   0x0000000000001151 <+24>:    mov    -0x210(%rbp),%rax
   0x0000000000001158 <+31>:    add    $0x8,%rax
   0x000000000000115c <+35>:    mov    (%rax),%rdx
   0x000000000000115f <+38>:    lea    -0x200(%rbp),%rax
   0x0000000000001166 <+45>:    mov    %rdx,%rsi
   0x0000000000001169 <+48>:    mov    %rax,%rdi
   0x000000000000116c <+51>:    call   0x1030 <strcpy@plt>
   0x0000000000001171 <+56>:    mov    $0x0,%eax
   0x0000000000001176 <+61>:    leave  
   0x0000000000001177 <+62>:    ret  
Run Code Online (Sandbox Code Playgroud)

然而,这个视频 …

c assembly x86-64 buffer-overflow stack-memory

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

x86 LEA 指令做不明确的事情

这是 C 代码:

int baz(int a, int b)
{
    return a * 11;
}
Run Code Online (Sandbox Code Playgroud)

它被编译为以下一组汇编指令(带有 -O2 标志):

baz(int, int):
        lea     eax, [rdi+rdi*4]
        lea     eax, [rdi+rax*2]
        ret
Run Code Online (Sandbox Code Playgroud)

lea指令计算第二个操作数(源操作数)的有效地址并将其存储在第一个操作数中。对我来说,第一条指令似乎应该将地址加载到 EAX 寄存器,但是,如果是这样,在第二条指令中将 RAX 乘以 2 没有意义lea,所以我推断这两lea条指令不会做完全相同的事情。

我想知道是否有人可以澄清这里到底发生了什么。

c assembly x86-64 instruction-set

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

如何解释 x86 汇编中“.ascii”指令生成的代码?

.asciix86 汇编中的指令如何工作?什么时候将 ASCII 码放入内存?我假设文本是放置在主内存中的机器代码的一部分,但是这里机器代码的yourText部分到底做了什么?

在 40100e 中, yourText代码部分的开头被放入 write 系统调用的缓冲区参数中。在 CI 中,会将其解释为将指针传递给字符串文字的第一个字符,但我不完全明白为什么它会转到更多代码,而不是在内存中找到文字的位置。

hwa.out:     file format elf64-x86-64

Disassembly of section .text:

0000000000401000 <_start>:
  401000:       48 c7 c0 01 00 00 00    mov    $0x1,%rax
  401007:       48 c7 c7 01 00 00 00    mov    $0x1,%rdi
  40100e:       48 c7 c6 2a 10 40 00    mov    $0x40102a,%rsi
  401015:       48 c7 c2 0d 00 00 00    mov    $0xd,%rdx
  40101c:       0f 05                   syscall 
  40101e:       48 c7 c0 3c 00 00 00    mov    $0x3c,%rax
  401025: …
Run Code Online (Sandbox Code Playgroud)

assembly x86-64 disassembly

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

如何打印 X86-64 程序集中命令行参数的数量?

我正在尝试打印 x86-64 中的汇编程序中存在的命令行参数的数量。

据我了解,参数信息存储在堆栈中。

我觉得我缺少一些关于如何检索堆栈中存储的项目的基本知识,但我不知道到底是什么。

在此输入图像描述

.file "args.s"

.globl main
.type main, @function

.section .data
format_string:
  .string "Argument: %s\n"

.section .text
main:
  pushq %rbp
  movq %rsp, %rbp

  popq %rsp                   ; get argc
  movq %rsp, %rdi             ; move argc to rdi, first parameter register
  movq $format_string, %rdi   ; pass in the string to be used and give the parameter
  call printf                 

  leave
  ret
.size main, .-main 
Run Code Online (Sandbox Code Playgroud)

assembly stack command-line x86-64

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