Tag: x86

了解ATT汇编语言

C版: int arith(int x, int y, int z) { int t1 = x+y; int t2 = z*48; int t3 = t1 & 0xFFFF; int t4 = t2 * t3; return t4; } ATT大会版同样的程序: x at%ebp + 8,y at%ebp + 12,z at%ebp + 16 movl 16(ebp), %eax leal (%eax, %eax, 2), %eax sall $4, %eax // […]

int64_t的宽度是64位吗?

对于以下代码 static inline float fix2float(int64_t f) { return (float)f / (1 << 60); // <– error here } 编译器给了我这些警告。 warning: left shift count >= width of type warning: division by zero 当64> 60时,为什么编译器会发出这些警告?

如何编写一个返回指向堆栈的指针的函数

在阅读了以下问题之后 ,我明白没有这样的事情存在(至少不是“便携式”)。 但是我主演单声道代码库中的以下代码片段 ,它返回指向堆栈的指针: static void * return_stack_ptr () { gpointer i; return &i; } 令我感到惊讶的是,上面的代码甚至可以在诸如PowerPC之类的arch上工作,我认为这只适用于x86(也许只有gcc)。 这是否适用于PowerPC?

从编译器asm输出反向设计数组维度/结构布局?

在此代码中,A和B是使用#define定义的常量。 A和B的值是多少? typedef struct { int x[A][B]; long y; } str1; typedef struct { char array[B]; int t; short S[A]; long u; } str2; void setVal(str1 *p, str2 *q) { long v1 = q->t; long v2 = q->u; p->y = v1+v2; } 为setVal过程生成以下汇编代码: setVal: movslq 8(%rsi), %rax addq 32(%rsi), %rax movq %rax, 184(%rdi) ret

x86汇编指令执行计数

大家好,我有一个代码,我想找到每个assembly线执行的次数。 我不关心是通过分析还是仿真,但我想要高精度的结果。 我曾经遇到过一个论坛,它提供了一些脚本代码,但我丢失了链接。 任何人都可以帮助我集思广益吗? 问候 编辑 :Okey我想我已经到了一半。 我根据一篇post对英特尔手册3A第16.4.5节提供的BTS(分支跟踪存储)进行了一些研究。 此function提供分支历史记录。 所以现在我需要你的帮助来查找是否有任何开源脚本或工具来执行此操作。 等待检查您的反馈 欢呼=)!

x86架构中的指令解码

我正在为我的实验室开发一个操作系统项目,我将使用指令指针和指令操作码。 现在我需要知道的是它是什么类型的指令。 为此,我正在从指令指针指向的地址读取数据。 该数据的第一个字节给出了指令类型。 例如,如果第一个字节是0xC6 ,则它是MOVB指令。 现在有些情况下指令指针的第一个字节是0x0F 。 根据文档0x0F ,这意味着它是一个双字节指令。 我的问题是这种类型的指令。 我不知道如何找出双字节指令的指令类型。 在那之后,我的第二个优先级是两个找出指令的操作数。 我不知道从代码中做到这一点。 任何示例代码将不胜感激 第三,需要找出指令的大小。 由于x86是可变长度,我想知道每个指令的大小。 起初我打算使用查找表,我将维护指令名称及其大小。 但后来我发现相同的指令可以有不同的长度。 例如,当我在.o文件上使用对象转储时,我发现了两条指令C6 00 62 ,用于MOVB $0x62,(%EAX)和C6 85 2C FF FF FF 00 ,用于MOVB $0x0,-0xD4(%EBP) 。 看这里两个指令类型相同( C6 )但是长度不同。 所以我需要回答这些问题。 如果有人能给我一些解决方案,我们将非常感激。

使用sse内在函数时如何摆脱循环?

__m128* pSrc1 = (__m128*) string; __m128 m0 = _mm_set_ps1(0); //null character while(1) { __m128 result = __m128 _mm_cmpeq_ss(*pSrc1, m0); //if character is \0 then break //do some stuff here pSrc1++; } 我有一个字符串,其长度可以是16的倍数。如果_mm_cmpeq_ss返回相等,我如何突破循环?

如何让gcc生成合适的代码来检查缓冲区是否充满了NUL字节?

我正在实现一个解析磁带存档的程序。 解析器逻辑的一部分是检查归档结束标记,该标记是一个充满NUL字节的512字节块。 我为此目的编写了以下代码,希望gcc能够很好地优化它: int is_eof_block(const char usth[static 512]) { size_t i; for (i = 0; i < 512; i++) if (usth[i] != '\0') return 0; return 1; } 但令我惊讶的是,gcc仍会为此生成可怕的代码,即使我明确允许它访问缓冲区中的整个512字节: is_eof_block: leaq 512(%rdi), %rax jmp .L239 .p2align 4,,10 .L243: addq $1, %rdi cmpq %rax, %rdi je .L242 .L239: cmpb $0, (%rdi) je .L243 xorl %eax, %eax […]

SSE加载和添加

假设我有两个向量由两个double类型的数组表示,每个数组大小为2.我想添加相应的位置。 因此假设向量i0和i1 ,我想将i0[0] + i1[0]和i0[1] + i1[1]在一起。 由于类型是double ,我需要两个寄存器。 诀窍是将i0[0]和i1[0] ,以及i0[1]和i1[1]放在另一个中,只需添加寄存器即可。 我的问题是,如果我调用_mm_load_ps(i0[0])然后_mm_load_ps(i1[0]) ,它会将它们分别置于低位和高位64位,还是会用第二次load替换寄存器? 如何将两个双打放在同一个寄存器中,以便我可以在之后调用add_ps ? 谢谢,

缓冲区溢出攻击格式

通常我们都会看到基本的缓冲区溢出格式,它有: – NOPs + shellcode + return_address 为什么我们不使用, NOPs + return_address + shellcode? 我们将返回地址指向shellcode的开头? 我猜这是因为如果漏洞位于main()中,我们可能会尝试在堆栈段外写入数据。 我对吗? 如果我,那是唯一的原因吗? 哦,是的,我不是指使用return-to-libc,ptrace等的其他类型的攻击; 我只是想知道为什么最基本的缓冲区溢出攻击以第一种方式展示而不是第二种方式。