SSE2指令(paddd xmm,m128)的工作真的很奇怪.代码告诉所有人.
#include <iostream>
using namespace std;
int main()
{
int * v0 = new int [80];
for (int i=0; i<80; ++i)
v0[i] = i;
int * v1 = new int [80];
for (int i=0; i<80; ++i)
v1[i] = i;
asm(
".intel_syntax noprefix;"
"mov rcx , 20;"
"mov rax , %0;"
"mov rbx , %1;"
"m_start:;"
"cmp rcx , 0;"
"je m_end;"
"movdqu xmm0 , [rax];"
"paddd xmm0 , [rbx];"
"movdqu [rax] , xmm0;"
"add rbx , 16;" …Run Code Online (Sandbox Code Playgroud) 我找到了很好的示例如何为闭包创建thunk,但它是32位版本:
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
struct env {
int x;
};
struct __attribute__((packed)) thunk {
unsigned char push;
struct env * env_addr;
unsigned char call;
signed long call_offset;
unsigned char add_esp[3];
unsigned char ret;
};
struct thunk default_thunk = {0x68, 0, 0xe8, 0, {0x83, 0xc4, 0x04}, 0xc3};
typedef void (* cfunc)();
struct thunk * make_thunk(struct env * env, void * code)
{
struct thunk * thunk = (struct thunk *)mmap(0,sizeof(struct thunk), PROT_WRITE | PROT_EXEC, MAP_PRIVATE | …Run Code Online (Sandbox Code Playgroud) 我现在还在学习装配.其余的代码在我理解之下并且宁愿自己解决,但涉及右移(shrl)的行是我不明白的.0x1if(4(%rsp)是什么意思?谢谢!
400783: 89 7c 24 ec mov %edi,-0x14(%rsp)
400787: c7 44 24 fc 00 00 00 movl $0x0,-0x4(%rsp)
40078e: 00
40078f: eb 14 jmp 4007a5 <f3+0x22>
400791: 8b 44 24 ec mov -0x14(%rsp),%eax
400795: 83 e0 01 and $0x1,%eax
400798: 85 c0 test %eax,%eax
40079a: 74 05 je 4007a1 <f3+0x1e>
40079c: 83 44 24 fc 01 addl $0x1,-0x4(%rsp)
**4007a1: d1 6c 24 ec shrl -0x1if (4(%rsp)***
4007a5: 83 7c 24 ec 00 cmpl $0x0,-0x14(%rsp)
4007aa: 75 e5 jne 400791 <f3+0xe> …Run Code Online (Sandbox Code Playgroud) 我刚才创建了一个简单的C程序.它是一个简单的命令行生成器,可以获取一些数字,打印结果并停止.我总是在编辑器的命令行环境中运行它,在程序运行后自动暂停,所以我省略了getchar()在最后添加一个.
我现在后悔这一点,因为我设法失去了源头.我现在所拥有的只是编译的.o和.exe文件,后者 - 当然 - 在打印输出后立即退出,因此它无法使用.它不是那么长,大约100行,但我想避免重写它.(另外,我甚至可能通过这种方式学到新东西.)
现在我对C语言有了非常基本的了解,并且在计算机程度x86汇编方面几乎为零(虽然我学会了8086组装微控制器的基础知识,但现在我认为它不会有用),所以我有点卡在这里.我可以添加getchar()像暂停函数到编译代码,或者有什么方法可以使.exe在退出之前停止,同时仍保持独立?
该程序将在Windows 10系统上运行.
我有memchr我要使非分支的这段代码:
.globl memchr
memchr:
mov %rdx, %rcx
mov %sil, %al
cld
repne scasb
lea -1(%rdi), %rax
test %rcx, %rcx
cmove %rcx, %rax
ret
Run Code Online (Sandbox Code Playgroud)
我不确定是否cmove是分支指令。是吗?如果是这样,如何重新排列我的代码,使其不分支?
assembly x86-64 cpu-architecture micro-optimization branch-prediction
考虑以下程序:
int main()
{
int arr[8];
}
Run Code Online (Sandbox Code Playgroud)
在 linux 20 上使用 gcc 9.3.0 编译时,文件的反汇编一开始看起来像这样(这不是上面代码的整个汇编!):
? 72: int dbg.main (int argc, char **argv, char **envp);
? ; var int[8] arr @ rbp-0x30
? ; var int64_t canary @ rbp-0x8
? 0x00001169 f30f1efa endbr64 ; test.c:2 { ; int main();
? 0x0000116d 55 push rbp
? 0x0000116e 4889e5 mov rbp, rsp
? 0x00001171 4883ec30 sub rsp, 0x30
Run Code Online (Sandbox Code Playgroud)
当arr只有 8 个整数 = 8 * 4 个字节长 ( sub rsp, 0x30)时,为什么汇编程序在堆栈上分配 …
我们在x86-64处理器中有16个通用寄存器:RAX,RCX,RDX,RBX,RSP,RBP,RSI,RDI,R9-15.x86-64处理器为我们提供了其他类型的寄存器.我的问题是:
考虑以下用 x86 汇编语言编写的函数
foo:
rep
nop
ret
Run Code Online (Sandbox Code Playgroud)
使用 NASM 汇编代码并反汇编它,gdb我们有:
(gdb) disas foo
Dump of assembler code for function foo:
0x0000000000000610 <+0>: pause ;pause ????
0x0000000000000612 <+2>: ret
0x0000000000000613 <+3>: nop WORD PTR cs:[rax+rax*1+0x0]
0x000000000000061d <+13>: nop DWORD PTR [rax]
End of assembler dump.
Run Code Online (Sandbox Code Playgroud)
它使用pause原始程序集中未提供的指令。为什么会这样?这是 NASM 故意记录的行为吗?那么如果一些早期的 x86cpu没有pause我们可以直接使用rep nop吗?
Intel x64 CPU 也可以运行 x86 asm。CPU 中是否有标志或模式来确定指令是否应解码为 x86 还是 x64?CPU 如何知道指令是 x86 还是 x64?
在 CPU 级别(不是操作系统级别!),是否可以混合使用 x86 和 x64 指令?
注意:在操作系统级别有很多关于这个问题的 SO 问答;我对CPU级别感兴趣。谈论库、文件等,都不是CPU层面的。
我遇到了使用IDA在Windows中调试64位二进制文件的问题.通常情况下,推送 RSP值应该扣除8.但偶尔,从IDA我看到RSP仅扣除2,然后是下一次推送8.
涉及的代码是
push rax
push rbx
push rsi
push rdi
Run Code Online (Sandbox Code Playgroud)
我对x64环境很新,因此任何人都可以解释这种行为吗?
由于数组的长度,我不能使用i32::from_ne_bytes(),但当然,以下工作特别是因为代码将仅在支持未对齐访问的 cpu 架构上运行(或者由于长度小,整个数组可能会被存储跨越多个 cpu 寄存器)。
fn main() {
let buf: [u8; 10] = [0, 0, 0, 1, 0x12, 14, 50, 120, 250, 6];
println!("1 == {}", unsafe{std::ptr::read(&buf[1])} as i32);
}
Run Code Online (Sandbox Code Playgroud)
但是有没有更干净的方法来做到这一点,同时仍然不复制数组?
我有一个名为SetCompare的简单delphi函数,它比较两个单例,如果它们不相等,则将一个值设置为另一个.
procedure SetCompare( A : single; B : single );
begin
if( A <> B ) then
A := B;
end;
Run Code Online (Sandbox Code Playgroud)
我试图将其转换为asm:
procedure SetCompare( A : Single; B : Single ); register;
begin
asm
mov EAX,A
mov ECX,B
cmp EAX,ECX
jne SetValue
@SetValue:
mov EAX,ECX
end;
end;
Run Code Online (Sandbox Code Playgroud)
这会有用吗?