标签: att

使用C++与程序集在运行时分配和创建新函数

我一直在研究一个(C++)项目,它需要完全动态分配的函数,这意味着malloc/new和mprotect,然后手动修改缓冲区到汇编代码.因此我完全想知道,我的这个"缓冲区"需要什么,因为它是任何其他_cdecl函数的复制品.例如:

int ImAcDeclFunc(int a, int b)
{
     return a + b;
}
Run Code Online (Sandbox Code Playgroud)

如果我想从字面上创建这个函数的副本,但是完全动态,那需要什么(并记住它是带有内联汇编的C++ )?对于初学者,我想我必须做这样的事情(或类似的解决方案):

// My main....
byte * ImAcDeclFunc = new byte[memory];
mprotect(Align(ImAcDeclFunc), pageSize, PROT_EXEC | PROT_READ | PROT_WRITE);
Run Code Online (Sandbox Code Playgroud)

在此之后我将不得不找出汇编代码ImAcDeclFunc(int a, int b);.现在我在组装时仍然很糟糕,那么这个函数将如何用于AT&T语法?这是我的大胆尝试:

push %ebp
movl %%ebp, %%esp
movl 8(%ebp), %%eax
movl 12(%ebp), %%edx
addl edx, eax
pop ebp
ret
Run Code Online (Sandbox Code Playgroud)

现在如果这段代码是正确的(我非常怀疑,请纠正我)我只需要在十六进制中找到这个代码的值(例如,'jmp'是0xE9而'inc'是0xFE),并直接使用这些值C++?如果我继续以前的C++代码:

*ImAcDeclFunc = 'hex value for push'; // This is 'push' from the first line
*(uint)(ImAcDeclFunc + 1) = 'address to …
Run Code Online (Sandbox Code Playgroud)

c++ gcc inline-assembly att dynamic-function

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

什么是pushl/popl%esp的汇编级表示?

C++

ATT大会

我试图理解以下两条指令的行为:

pushl %esp
Run Code Online (Sandbox Code Playgroud)

和:

popl %esp
Run Code Online (Sandbox Code Playgroud)

请注意,它们将计算出的值存储回来%esp.

我正在独立地考虑这些指令,而不是按顺序.我知道存储的值%esp总是递增/递减之前的值,但是我怎么能用汇编语言表示行为呢?这是我到目前为止所提出的:

推送:

movl %esp, %edx     1. save value of %esp
subl  $4, %esp      2. decrement stack pointer
movl %edx, (%esp)   3. store old value of %esp on top of stack
Run Code Online (Sandbox Code Playgroud)

对于pop:

movl (%esp), %esp   You wouldn’t need the increment portion. 
Run Code Online (Sandbox Code Playgroud)

它是否正确?如果没有,我哪里错了?谢谢.

x86 assembly stack att

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

关于[base + index*scale + disp]的几个问题

英特尔和AT&T语法中内存寻址的一般形式如下:

[base + index*scale + disp]
disp(base, index, scale)
Run Code Online (Sandbox Code Playgroud)

我的问题如下:

  • 可以baseindex任意注册?
  • 可以scale采用什么值,是1,2,4和8(默认值为1)?
  • indexdisp可互换的(唯一的区别index是寄存器disp是一个常数)?

x86 assembly att intel-syntax addressing-mode

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

x86汇编代码中的指针引用

我正在读我的教科书,它有交换功能的代码:

在C:

int exchange(int *xp, int y) {
 int x = *xp;
 *xp = y;
 return x; 
}
Run Code Online (Sandbox Code Playgroud)

在x86带注释的程序集中:

// xp is at %ebp + 8, y at %ebp + 12
movl 8(%ebp), %edx      // get xp
movl (%edx), %eax       // get x at xp
movl 12(%ebp), %ecx     // get y
movl %ecx, (%edx)       // store y at xp
Run Code Online (Sandbox Code Playgroud)

因此,根据我的理解,如果int*xp指向地址A处的int I,则汇编代码的第一行将A存储在%edx处.然后在第二行中取消引用并存储在%eax中.

如果这是真的,我想知道为什么第1行的"8(%ebp)"没有取消引用指针,将int存储在%edx而不是地址A中?这不是括号在汇编中做的吗?

或者这是否意味着当指针被推入堆栈时,指针的地址被推上而不是它所持有的值,因此8(%ebp)技术上持有&xp?

只是想澄清我的理解是否正确.

c x86 assembly pointers att

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

ljmp指令在linux内核fork系统调用中做了什么?

我正在研究linux内核源码(旧版本0.11v).当我检查fork系统调用时,有一些asm代码用于上下文切换,如下所示:

/*
 * switch_to(n) should switch tasks to task nr n, first
 * checking that n isn't the current task, in which case it does nothing.
 * This also clears the TS-flag if the task we switched to has used
 * tha math co-processor latest.
 */
#define switch_to(n) {\
struct {long a,b;} __tmp; \
__asm__("cmpl %%ecx,current\n\t" \
    "je 1f\n\t" \
    "movw %%dx,%1\n\t" \
    "xchgl %%ecx,current\n\t" \
    "ljmp *%0\n\t" \
    "cmpl %%ecx,last_task_used_math\n\t" \
    "jne 1f\n\t" \
    "clts\n" \
    "1:" \
    ::"m" …
Run Code Online (Sandbox Code Playgroud)

x86 assembly gnu-assembler linux-kernel att

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

程序集cltq和movslq的区别

计算机系统的第3章程序员的观点(第2版)提到了
cltq相当于movslq %eax, %rax.

为什么他们创建一个新的指令(cltq)而不是仅使用movslq %eax,%rax?这不是多余的吗?

x86 assembly x86-64 instruction-set att

7
推荐指数
1
解决办法
2万
查看次数

分裂导致括号不平衡

在GNU as(GNU汇编程序)中,以下代码无错误地汇编:

mov $(80 * 24 + 4), %cx
Run Code Online (Sandbox Code Playgroud)

但是,此代码不会:

mov $(80 * 24 / 4), %cx
Run Code Online (Sandbox Code Playgroud)

发出非常意外的错误:

example.S: Assembler messages:
example.S:42: Error: unbalanced parenthesis in operand 1.
Run Code Online (Sandbox Code Playgroud)

唯一的区别是后者使用除法而不是加法.根据手册,这应该是有效.

($<expression>将一个立即嵌入到已组合的输出中;即一个常量.算术在"编译时"执行.我可以计算出数学,但它在扩展形式中更有意义.)

x86 assembly att

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

at&t汇编中'push'和'pushq'之间的区别是什么

我最近开始寻求更好地理解我的计算机是如何工作的.我的问题是关于push和pushq之间的区别.

我知道push会将一个值写入堆栈,我的假设是pushq做了类似的事情.q在那里的事实让我觉得应该有一个微妙的区别,但我似乎无法理解差异.

我说在使用命令'layout asm'使用gdb调试文件/ lib/udev/iphone-set-info时考虑这个问题.

有问题的代码是:

pushq  $0x0
push   %r9
Run Code Online (Sandbox Code Playgroud)

我知道$ 0x0对于NULL是十六进制的,而%r9是通用寄存器之一.这只是意味着Null我们写入堆栈,其上面写有寄存器%r9吗?

linux assembly gdb reverse-engineering att

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

标签和汇编中的功能有什么区别

一直通过AT&T语法关注youtube上的汇编教程。我刚刚学习了使用.type指令声明(如果在这里是正确的术语)函数,例如:

.type MyFunction, @function
Run Code Online (Sandbox Code Playgroud)

现在,我可以像下面这样定义我的函数:

MyFunction:
    <code here>
Run Code Online (Sandbox Code Playgroud)

然后在任何时候调用它:

call MyFunction
Run Code Online (Sandbox Code Playgroud)

我知道在教程之前,我们只是在创建一个附加到一些代码的标签:

MyLabel:
    <code here>
Run Code Online (Sandbox Code Playgroud)

然后可以这样称呼它:

call MyLabel
Run Code Online (Sandbox Code Playgroud)

所以我的问题是:

用.type声明的函数和仅用标签声明的'function'到底有什么区别?什么时候应该使用另一个,或者这有关系吗?

assembly gnu-assembler att

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

X86中mov和movl指令的区别?我在阅读汇编时遇到了一些麻烦

最近,我读了一些关于计算机科学的书。我编写了一些 C 代码,并使用gccobjdump反汇编了它们。

以下C代码:

#include <stdio.h>
#include <stdbool.h>

int dojob()
{
    static short num[ ][4] = { {2, 9, -1, 5},   {3, 8, 2, -6}};
    static short *pn[ ] = {num[0], num[1]};
    static short s[2] = {0, 0};
    int i, j;

    for (i=0; i<2; i++) {
        for (j=0; j<4; j++){
            s[i] += *pn[i]++;
        }
        printf ("sum of line %d: %d\n", i+1, s[i]);
    }

    return 0;
}

int main ( )
{
    dojob();
}
Run Code Online (Sandbox Code Playgroud)

得到以下汇编代码(AT&T 语法;只有函数dojob …

x86 assembly gcc objdump att

6
推荐指数
1
解决办法
3万
查看次数