x86-64相关内容
我正在尝试在 64 位 Linux 上 GCC 的扩展内联 ASM 中输出相同的字符串两次. int main(){const char* test = "test\n";汇编("movq %[test], %%rdi\n"//调试器显示 rdi = *字符串的地址*"movq $0, %%rax\n""推 %%rbp\n""推 %%rbx\n""调用 printf\n""弹出 %%rbx\n"
..
何时在 x86 中使用 size 指令似乎有点模棱两可.此 x86 组装指南 内容如下: 一般来说,给定内存中数据项的预期大小地址可以从它所在的汇编代码指令中推断出来参考.例如,在上述所有指令中,大小可以从寄存器的大小推断出内存区域操作数.当我们加载 32 位寄存器时,汇编器可以推断我们所指的内存区域是 4 字节宽.当我们将一个字节寄存器的值存储到内存时,汇编器可以推断出我们希望地址指向单个
..
关于下面的小代码,在另一篇关于结构大小和正确对齐数据的可能性的文章中进行了说明: 结构{字符数据1;短数据2;整数数据3;字符数据4;} X;未签名的乐趣(无效){x.Data1=1;x.Data2=2;x.Data3=3;x.Data4=4;返回(大小(x));} 我得到了相应的反汇编(64位) 0000000000000000 :0: 55 推 %rbp1: 48 89 e5 m
..
这是代码(exit.s): .section .data,.section .text,.globl _start_开始:movl $1, %eaxmovl $32, %ebx系统调用 当我执行 " 作为 exit.s -o exit.o && ld exit.o -o exit -e _start && ./exit" 返回的是“Bus error: 10",而“echo $?"的输出
..
免责声明:言语无法描述我对 AT&T 风格语法的厌恶程度 我有一个问题,希望是由注册破坏引起的.如果没有,我有一个更大的问题. 我使用的第一个版本是 static unsigned long long rdtscp(void){无符号整数你好,你好;__asm__ __volatile__("rdtscp" : "=a"(lo), "=d"(hi));return (unsigned
..
我遇到了一个有趣的问题.我忘了我使用的是 64 位机器 &OS 并编写了 32 位汇编代码.我不知道如何编写 64 位代码. 这是 Linux 上 Gnu 汇编程序的 x86 32 位汇编代码(AT&T 语法). //hello.S#include #include #define 标准输出 1.数据你好:.ascii "你好世界\n";你好:.文本.globl _start_开始:mov
..
GCC 4.4.3 生成了以下 x86_64 程序集.令我困惑的部分是 mov %eax,%eax.将寄存器移至自身?为什么? 23b6c: 31 c9 xor %ecx,%ecx ;移位的 0 值23b6e: 80 7f 60 00 cmpb $0x0,0x60(%rdi);它转移了吗?23b72: 74 03 je 23b7723b74: 8b 4f 64 mov 0x64(%rdi),%
..
我是汇编编程的新手,正在使用 GNU 汇编器在 Ubuntu x86_64 桌面上完成Programming Ground Upv2.20.1. 我已经能够组装/链接执行我的代码,直到我开始使用 pushl/popl 指令来操作堆栈.以下代码无法组装: .section .data # 空.section .text.globl _start_开始:pushl $1 # 将值 1 压入堆
..
我正在研究 OSX 上使用的 x86_64 的调用约定,并正在阅读 uint8_t[3] 之类的东西,因为它更小比聚合类型分类规则 1 强加的四个八字节限制(第 18 页靠近底部). 编译后我看到它被作为指针传递.(我正在 OSX 10.11.6 上使用 Xcode 7.3.1 中的 clang-703.0.31 进行编译). 我用来编译的示例源如下: #include #定义类型字
..
我有一个简单的调试器(使用 ptrace :http://pastebin.com/D0um3bUi)来计算为给定的输入可执行程序执行的指令数.使用ptrace单步执行方式对指令进行计数. 为此,当程序 1) 的可执行文件(来自 gcc main.c 的 a.out)作为输入提供给我的测试调试器时,它会在执行指令时打印大约 100k.当我使用 -static 选项时,它给出了 10681 条
..
我目前正在阅读这本书:“计算机系统 - 程序员的观点".我发现,在 x86-64 架构上,我们仅限于 6 个整数参数,这些参数将传递给寄存器中的函数.下一个参数将在堆栈上传递. 而且,第一个最多 8 个 FP 或向量参数在 xmm0..7 中传递. 为什么不使用浮点寄存器来存储下一个参数,即使参数不是单/双精度变量? 将数据存储在寄存器中比将数据存储到内存然后从内存中读取要高效得
..
我想知道这里是否有人有一些很好的 C++ CPUID 实现示例,可以从任何托管 .net 语言中引用. 另外,如果不是这样的话,我应该知道 X86 和 X64 之间的某些实现差异吗? 我想使用 CPUID 获取有关运行我的软件的机器的信息(崩溃报告等...),并且我希望尽可能广泛地兼容所有内容. 我问这个问题的主要原因是,尽管我对 CPU 寄存器等有基本的了解,但在编写可能是所有
..
在我的 64 位英特尔机器上,以下代码有效: mov rdi, 1 而这个看起来相当类似的会产生警告并且不起作用: add r10, 1 我应该坚持第一还是我错过了什么?这种行为似乎很尴尬. 代码 nr 2 产生的警告: 警告:有符号的双字立即超出范围 解决方案 mov r/m64, imm64 有操作码,但 add r/m64 没有操作码,imm64 在 x86-64 指
..
在 x64 上,从 64 位绝对地址加载(即取消引用 64 位立即数)可以通过 movabs addr64, %rax 但是,当目标寄存器不是 rax 时,汇编器会给出一条错误消息,指出 movabs 的操作数大小不匹配.我错过了什么? 解决方案 来自MOV说明文档您可以看到您可以将 64 位立即移动到任何寄存器,但加载/存储涉及 64 位立即绝对地址 只能与 Areg 一起使用
..
在 x64 上,每个 PUSH 指令是否推送 8 字节的倍数?如果没有,它会推动多少? 另外,每个函数参数消耗多少堆栈空间? 解决方案 没有,但在实践中,总是将一个 8 字节的值压入堆栈. 函数参数消耗不同数量的堆栈空间,具体取决于函数参数的大小以及它是在堆栈中、寄存器中还是通过引用传递. 如果通过压入在堆栈中传递函数参数,那么有方便的压入8字节的压入指令这一事实强烈建议
..
我看到一个简单的存储循环的性能出乎意料地糟糕,它有两个存储:一个向前跨度为 16 字节,另一个总是到相同的位置1,如下所示: volatile uint32_t 值;无效的奇怪_cpp(size_t iters,uint32_t* 输出){uint32_t x = 值;uint32_t *rdx = 输出;易失性 uint32_t *rsi = 输出;做 {*rdx = x;*rsi = x;r
..
我正在尝试在我的 .text 部分中用汇编语言定义一个字节.我知道数据应该转到 .data 部分,但我想知道为什么在我这样做时它会给我一个分段错误.如果我在 .data 中定义字节,它不会给我任何错误,与 .text 不同.我正在使用运行 Mint 19.1 的 Linux 机器并使用 NASM + LD 来编译和链接可执行文件. 这在没有分段错误的情况下运行: 全局 _start.dat
..
我尝试使用 scanf 输入四个浮点数,将它们存储到堆栈中,然后使用 vmovupd 将它们复制到寄存器以供使用.我的问题是当我尝试输出这 4 个数字时,程序在 printf 处出现段错误. 我认为它与堆栈有关,但我尝试多次弹出(一次多条指令)但无济于事.我对汇编编码还是个新手,所以使用 gdb 对我来说有点太高级了. 您会注意到我包含了一个名为 debug 的文件.它允许我查看寄存器
..
假设 %edi 包含 x 并且我想仅使用 2 个连续的 leal 指令得到 37*x,我将如何处理? 例如要获得 45 倍,您可以这样做 leal (%edi, %edi, 8), %edileal (%edi, %edi, 4), %eax (返回) 我一生都无法弄清楚用什么数字代替 8 和 4,这样结果 (%eax) 将是 37x 解决方案 在 -O3 处,gcc 将发出(G
..
在 /O2(发布)模式下查看 Visual Studio (2015U2) 生成的程序集时,我看到这段“手动优化"的 C 代码被转换回乘法: int64_t calc(int64_t a) {返回 (a
..