标签: x86-64

如果涉及 MAP_FIXED,无限堆栈不能超过最初的 132KiB?

我正在使用堆栈进行一些实验,以下内容让我陷入困境。

可以看出Linux在大小上有初始[stack]映射132KiBulimit -s unlimited如果我们进行相应的调整,我们可以进一步扩展堆栈rsp。所以我设置ulimit -s unlimited并运行了以下程序:

PAGE_SIZE     equ 0x1000

;mmap staff
PROT_READ     equ 0x01
PROT_WRITE    equ 0x02
MAP_ANONYMOUS equ 0x20
MAP_PRIVATE   equ 0x02
MAP_FIXED     equ 0x10

;syscall numbers
SYS_mmap      equ 0x09
SYS_exit      equ 0x3c

section .text

global _start

_start:
    ; page alignment
    and rsp, -0x1000

    ; call mmap 0x101 pages below the rsp with fixed mapping
    mov rax, SYS_mmap
    lea rdi, [rsp - 0x101 * PAGE_SIZE]
    mov rsi, PAGE_SIZE
    mov …
Run Code Online (Sandbox Code Playgroud)

linux assembly callstack mmap x86-64

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

x86_64 无法将 64 位值添加到 rax,“'add' 上的操作数不匹配”

我正在尝试组装一些 64 位代码,但组装失败了:

addq $0xffffff7fc0005000, %rax
Run Code Online (Sandbox Code Playgroud)

有错误:

`add' 的错误操作数类型不匹配

第一个操作数是一个 64 位值,后者是一个应该组装好的寄存器。该指令前面有一个.code64伪操作。我正在组装

x86_64-elf-as test.s -o test.o --64
Run Code Online (Sandbox Code Playgroud)

至于汇编器本身,当用--version它调用时返回:

GNU assembler (GNU Binutils) 2.32
Copyright (C) 2019 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or later.
This program has absolutely no warranty.
This assembler was configured for a target of `x86_64-elf'.
Run Code Online (Sandbox Code Playgroud)

assembly x86-64 gnu-assembler immediate-operand

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

C 程序高 4 字节的指针地址异常

在程序的一部分中,我以两种不同的方式打印出相同的指针。

vpx_codec_iface_t *ptr = vpx_codec_vp9_cx();
printf("ptr1 %p\n", ptr);
printf("ptr2 %p\n", vpx_codec_vp9_cx());
Run Code Online (Sandbox Code Playgroud)

这奇怪地导致以下输出。

ptr1 FFFFFFFFDAF9CED0
ptr2 00000000DAF9CED0
Run Code Online (Sandbox Code Playgroud)

玩弄这个程序,我可以通过添加一些代码或添加一些换行符来“修复”错误。

int x = 0;
vpx_codec_iface_t *ptr = vpx_codec_vp9_cx();
printf("ptr1 %p\n", ptr);
printf("ptr2 %p\n", vpx_codec_vp9_cx());
printf("x=%d\n", x);
Run Code Online (Sandbox Code Playgroud)

这导致以下输出。

ptr1 0000000066A7CED0
ptr2 0000000066A7CED0
x=0
Run Code Online (Sandbox Code Playgroud)

什么可能导致这种行为?我在 Windows 10 上使用 Visual Studio 2019 编译器,为 x64 进行编译。函数调用vpx_codec_vp9_cx()是在vpxmd.lib其中实现的,来自libvpx项目。

编辑:我仍在查看您的答案和评论,但我在下面创建了一个最小示例。不幸的是,它涉及构建整个 vpx 库,因此我需要一些时间来简化该部分。

#include <stdio.h>
#include "vpx/vpx_encoder.h"

int main(int argc, char **argv) {
  printf("This is main\n");
  vpx_codec_iface_t *ptr = vpx_codec_vp9_cx();
  int x = 0;
  printf("ptr1 …
Run Code Online (Sandbox Code Playgroud)

c x86-64

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

为什么会生成不同的汇编代码?哪个更好?

#include <cstdint>

uint64_t hr1(const uint64_t x, const bool a, const int n) noexcept
{
    if (a) {
        return x | (a << n);
    }
    return x;
}

uint64_t hr2(const uint64_t x, const bool a, const int n)
{
    return x | ((a ? 1ull : 0) << n);
}
Run Code Online (Sandbox Code Playgroud)

https://godbolt.org/z/gy_65H

hr1(unsigned long, bool, int):
  mov rax, rdi
  test sil, sil
  jne .L4
  ret
.L4:
  mov ecx, edx
  mov esi, 1
  sal esi, cl
  movsx rsi, esi
  or rax, rsi
  ret …
Run Code Online (Sandbox Code Playgroud)

c++ optimization assembly gcc x86-64

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

像 mov byte ptr [rax + rdx-1], 00 这样的指令是什么意思,其中 rax 不是指针

沉迷于汇编程序的学习

mov byte ptr [rax+rdx-01],00

RAX=00000004
RDX=2295EA3B878
Run Code Online (Sandbox Code Playgroud)

mov [r10+rsi],al

RAX=0000000000000065
RSI=000002295EA3B878
R10=0000000000000000
Run Code Online (Sandbox Code Playgroud)

很清楚mov al byte ptr。但我不明白什么意思 [rax+rdx-01][r10+rsi] rax 和 r10 不是指针。

在大多数情况下,我面临[RAX+C1]rax 是指针而 C1 是偏移量的情况,但是我不知道寄存器存储某些值而不是指针时的含义

assembly x86-64 cpu-registers offset addressing-mode

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

Intel CPU 上的 SYSENTER

所以AFAIK syscall指令,相当于AMD 的sysenter。所以理论上应该只能在 AMD 芯片上找到一条syscall指令,对吗?好吧,显然情况并非如此,因为我正在处理 ntdll.dll 和 ntdll.dll(WOW64 版本),我发现常规版本使用syscall而来自 WOW64 的 ntdll.dll 使用sysenter。这是为什么?

x86 assembly winapi x86-64 system-calls

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

为什么我的内核会立即重置我的机器?

我正在使用 Buildroot 2020.02.1 为安装了 AMD GX-222GC SOC 的 PC 构建自定义内核。

默认的外部工具链是来自 CodeBench 的 amd-2016.11-19。使用该工具链构建的内核正确启动。 相反,如果我使用由 buildroot 自动构建的工具链构建相同的内核、相同的配置,则内核不会启动!甚至没有内核恐慌,机器只是重置。

很明显,问题与工具链有关。

这些是 gcc -v 的结果

代码台

$ output/host/usr/bin/x86_64-amd-linux-gnu-gcc -v
Using built-in specs.
COLLECT_GCC=/media/AAA/tmp/buildroot_toolchain/output/host/opt/ext-toolchain/bin/x86_64-amd-linux-gnu-gcc
COLLECT_LTO_WRAPPER=/media/AAA/tmp/buildroot_toolchain/output/host/opt/ext-toolchain/bin/../libexec/gcc/x86_64-amd-linux-gnu/6.2.0/lto-wrapper
Target: x86_64-amd-linux-gnu
Configured with: /scratch/jmyers/amd-lite/src/gcc-6-2016.11/configure --build=i686-pc-linux-gnu --host=i686-pc-linux-gnu --target=x86_64-amd-linux-gnu --enable-threads --disable-libmudflap --disable-libstdcxx-pch --enable-extra-sgxxlite-multilibs --with-arch=btver2 --with-cpu=btver2 --with-gnu-as --with-gnu-ld --with-specs='-D__CS_SOURCERYGXX_MAJ__=2016 -D__CS_SOURCERYGXX_MIN__=11 -D__CS_SOURCERYGXX_REV__=19' --enable-languages=c,c++ --enable-shared --enable-lto --enable-symvers=gnu --enable-__cxa_atexit --with-glibc-version=2.24 --with-pkgversion='Sourcery CodeBench Lite 2016.11-19' --with-bugurl=https://sourcery.mentor.com/GNUToolchain/ --disable-nls --prefix=/opt/codesourcery --with-sysroot=/opt/codesourcery/x86_64-amd-linux-gnu/libc --with-build-sysroot=/scratch/jmyers/amd-lite/install/opt/codesourcery/x86_64-amd-linux-gnu/libc --with-gmp=/scratch/jmyers/amd-lite/obj/pkg-2016.11-19-x86_64-amd-linux-gnu/amd-2016.11-19-x86_64-amd-linux-gnu.extras/host-libs-i686-pc-linux-gnu/usr --with-mpfr=/scratch/jmyers/amd-lite/obj/pkg-2016.11-19-x86_64-amd-linux-gnu/amd-2016.11-19-x86_64-amd-linux-gnu.extras/host-libs-i686-pc-linux-gnu/usr --with-mpc=/scratch/jmyers/amd-lite/obj/pkg-2016.11-19-x86_64-amd-linux-gnu/amd-2016.11-19-x86_64-amd-linux-gnu.extras/host-libs-i686-pc-linux-gnu/usr --with-isl=/scratch/jmyers/amd-lite/obj/pkg-2016.11-19-x86_64-amd-linux-gnu/amd-2016.11-19-x86_64-amd-linux-gnu.extras/host-libs-i686-pc-linux-gnu/usr --enable-libgomp --enable-libitm --enable-libatomic --disable-libssp --disable-libcc1 --enable-poison-system-directories --with-python-dir=x86_64-amd-linux-gnu/share/gdb/python --with-build-time-tools=/scratch/jmyers/amd-lite/install/opt/codesourcery/x86_64-amd-linux-gnu/bin --with-build-time-tools=/scratch/jmyers/amd-lite/install/opt/codesourcery/x86_64-amd-linux-gnu/bin SED=sed …
Run Code Online (Sandbox Code Playgroud)

x86-64 linux-kernel toolchain buildroot

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

算术恒等式和 EFLAGS

由于 ?x = not(x)+1 则意味着 ab = a+not(b)+1,那么

sub rax, rcx
Run Code Online (Sandbox Code Playgroud)

相当于

mov temp, rcx
not temp
add rax, temp
add rax, 1
Run Code Online (Sandbox Code Playgroud)

temp 某些寄存器被认为是易失性的?

换句话说,后者是否以完全相同的方式影响 EFLAGS?如果不是,又怎么能强求呢?

x86 assembly x86-64 eflags

0
推荐指数
2
解决办法
136
查看次数

为什么向 numeric_limits&lt;float&gt;::min() 加 1 会返回 1?

为什么从 float max 中减去 1 会返回一个合理的值,而向 float min 中加 1 会返回 1?

我认为,如果您添加或减去一个小于该特定量级的 epsilon 的值,则不会发生任何事情,也不会增加或减少。

这是我用没有标志的 g++ 编译并在 x86_64 上运行的代码。

#include <limits>
#include <iostream>

int main() {
    float min = std::numeric_limits<float>::min() + 1;
    float max = std::numeric_limits<float>::max() - 1;

    std::cout << min << std::endl << max << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出这个:

1
3.40282e+38
Run Code Online (Sandbox Code Playgroud)

我希望它输出这个:

-3.40282e+38
 3.40282e+38
Run Code Online (Sandbox Code Playgroud)

c++ floating-point gcc x86-64 floating-accuracy

0
推荐指数
2
解决办法
129
查看次数

为什么被调用者不首先使用调用者保存的寄存器?

我们知道,根据 x86-64 约定,寄存器%rbx%rbp%r12%r15被归类为被调用者保存的寄存器。While%r10%r111是调用者保存的寄存器。但是当我在大多数情况下编译 C 代码时,例如函数P调用Q,我看到以下函数的汇编代码Q

Q:
   push %rbx
   movq %rdx, %rbx
   ...
   popq %rbx
   ret
Run Code Online (Sandbox Code Playgroud)

我们知道,由于%rbx是一个被调用者保存的寄存器,我们必须将它存储在堆栈中,并在P以后为调用者恢复它。

但它不会更简洁并通过使用调用者保存的寄存器来保存堆栈操作%r10

Q:
   movq %rdx, %r10
   ...
   ret
Run Code Online (Sandbox Code Playgroud)

所以被调用者不需要担心保存和恢复调用者的寄存器,因为调用者在调用被调用者之前已经把它推到了堆栈?

c assembly x86-64 calling-convention compiler-optimization

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