标签: intel-syntax

在计算像"$ - label"这样的字符串长度时,美元符号($)在x86汇编中的含义是什么?

例如,如果我们编写一个简单的hello world类型程序,.data部分可能包含以下内容:

section .data

msg     db      'Enter something: '
len     equ     $ - msg
Run Code Online (Sandbox Code Playgroud)

这个例子中的$代表什么,为什么$ - msg等于字符串的长度?

x86 assembly intel-syntax

32
推荐指数
4
解决办法
4万
查看次数

关于AT&T x86语法设计的问题

  1. 任何人都可以向我解释为什么AT&T语法中的每个常量前面都有一个"$"?
  2. 为什么所有寄存器都有'%'?
  3. 这只是让我做很多蹩脚打字的另一种尝试吗?
  4. 另外,我是唯一一个发现:16(%esp)真的违反直觉[esp+16]吗?
  5. 我知道它编译成同样的东西,但为什么有人想要输入很多'$'和'%'而不需要? - 为什么GNU选择此语法作为默认语法?
  6. 另一件事,为什么at&t语法中的每条指令前面都有一个:l? - 我知道它的操作数大小,但为什么不让汇编程序弄清楚呢?(我是否想要在不是那么大的操作数上做一个movl?)
  7. 最后一件事:为什么mov参数倒置了?

是不是合乎逻辑:

eax = 5
mov eax, 5
Run Code Online (Sandbox Code Playgroud)

at at&t是:

mov 5, eax
5 = a (? wait what ?)
Run Code Online (Sandbox Code Playgroud)

注意:我不是想乱跑.我只是不明白他们所做的设计选择,我试图了解他们为什么做了他们所做的.

x86 assembly att intel-syntax

18
推荐指数
3
解决办法
1894
查看次数

x86-64 GAS Intel 语法中像“[RIP + _a]”这样的 RIP 相关变量引用如何工作?

考虑 x64 Intel 程序集中的以下变量引用,其中变量a.data节中声明:

mov eax, dword ptr [rip + _a]
Run Code Online (Sandbox Code Playgroud)

我很难理解这个变量引用是如何工作的。既然a是对应于变量运行时地址的符号(带重定位),如何[rip + _a]解引用正确的内存位置a?事实上,rip保存当前指令的地址,它是一个大的正整数,所以加法会导致错误的地址a

相反,如果我使用 x86 语法(非常直观):

mov eax, dword ptr [_a]
Run Code Online (Sandbox Code Playgroud)

,我收到以下错误:64 位模式不支持 32 位绝对寻址

有什么解释吗?

  1 int a = 5;
  2 
  3 int main() {
  4     int b = a;
  5     return b;
  6 }   
Run Code Online (Sandbox Code Playgroud)

编译gcc -S -masm=intel abs_ref.c -o abs_ref::

  1     .section    __TEXT,__text,regular,pure_instructions
  2     .build_version macos, 10, 14
  3 …
Run Code Online (Sandbox Code Playgroud)

assembly x86-64 gnu-assembler intel-syntax addressing-mode

14
推荐指数
1
解决办法
2893
查看次数

如何使用Intel语法内联汇编在GCC中设置变量?

为什么这段代码没有设置temp为1?我该怎么做呢?

int temp;
__asm__(
    ".intel_syntax;"
    "mov %0, eax;"
    "mov eax, %1;"
    ".att_syntax;"
    : : "r"(1), "r"(temp) : "eax");
printf("%d\n", temp);
Run Code Online (Sandbox Code Playgroud)

gcc inline-assembly intel-syntax

12
推荐指数
3
解决办法
2万
查看次数

x86 cmpl和jne

我正在跟踪一些x86代码进行分配,我想知道究竟"cmpl"究竟是什么以及如何预测"jne"是否会被满足.

80484bf:    83 7d f0 07             cmpl   $0x7,-0x10(%ebp)
80484c3:    75 16                   jne    80484db
Run Code Online (Sandbox Code Playgroud)

此外,这使用Intel语法.

谢谢.

x86 intel-syntax

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

使用GNU Assember Intel语法进行内存寻址

我读过这个页面,其中包含了针对GAS的英特尔和AT&T语法之间的差异的良好列表,但它没有涵盖仅指定具有位移的地址的情况.

在这里,我用AT&T语法组装了四行:

                         .text
0000 48C7C008000000      mov    $8, %rax
0007 488B042508000000    mov    (8), %rax
000f 4889F0              mov    %rsi, %rax
0012 488B06              mov    (%rsi), %rax
Run Code Online (Sandbox Code Playgroud)

正如预期的那样,前两行是不同的.第一个将立即值8移动到rax中,第二个将地址8的内容移动到rax中.但是使用Intel语法我会得到以下奇怪的行为:

                         .text
                         .intel_syntax
0000 48C7C008000000      mov    %rax, 8
0007 48C7C008000000      mov    %rax, [8]
000e 4889F0              mov    %rax, %rsi
0011 488B06              mov    %rax, [%rsi]
Run Code Online (Sandbox Code Playgroud)

这里第一行和第二行汇编到相同的机器代码!首先我认为方括号是错误的,所以我在测试中添加了第三行和第四行,并且方括号对于内存寻址至少在涉及寄存器时起作用.

我读过的所有文档都显示了至少有一个基址或索引寄存器的内存寻址示例,有时还有一个比例和位移,但从不仅仅是位移.

我确实有使用NASM汇编程序的英特尔语法经验,它可以区分mov rax, 8mov rax, [8].

这是GAS中的错误吗?或者如果没有,我如何指定NASM的等效物mov rax, [8]

我意识到指定一个仅位移地址可能并不常见,但我希望通过这种语法完全理解所有内存寻址形式.

assembly gnu-assembler intel-syntax

8
推荐指数
1
解决办法
3878
查看次数

关于[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
查看次数

使用".intel_syntax noprefix"如何获取标签的内存地址?

我正在学习如何创建组装和链接的真实模式程序:

  • GCC汇编程序版本2.25
  • Binutils版本2.25
  • GCC版本5.2.0

我使用没有指定前缀的Intel语法 .intel_syntax noprefix

我想将字符串的地址加载到SI寄存器中.我知道,如何在NASM中引用内存位置,但是当我在GNU汇编程序代码中执行相同操作时,它只将字符串的WORD移动到寄存器而不是标签的地址.

我的代码是:

.code16
.intel_syntax noprefix

mov cx, 11
mov si, name
mov di, 0x7E00
push di
rep cmpsb
pop di
je LOAD
Run Code Online (Sandbox Code Playgroud)

当我用GCC编译它时,我可以在调试器中看到处理器执行的操作:

mov si, WORD ptr ds:0x7d2d
Run Code Online (Sandbox Code Playgroud)

但我想将字符串的地址移入寄存器,而不是它指向的数据.

我还尝试在名称周围放置方括号,如下所示:

.code16
.intel_syntax noprefix

mov cx, 11
mov si, [name]
mov di, 0x7E00
push di
rep cmpsb
pop di
je LOAD
Run Code Online (Sandbox Code Playgroud)

它没有任何区别.

NASM我知道这个汇编代码有效:

mov si, name
Run Code Online (Sandbox Code Playgroud)

NASM将生成将地址移动name到寄存器SI的指令.

我的问题:有没有办法强制GCC使用带有无前缀的英特尔语法将符号的地址加载到寄存器中?

x86 assembly real-mode gnu-assembler intel-syntax

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

如何设置 gcc 以永久使用 intel 语法?

我有以下代码,可以用 gcc 命令很好地编译gcc ./example.c。程序本身调用函数“add_two”,它只是将两个整数相加。要在扩展汇编指令中使用 intel 语法,我需要首先切换到 intel,然后再切换回 AT&T。根据 gcc 文档,可以使用gcc -masm=intel ./exmaple.

每当我尝试使用 switch 编译它时,-masm=intel它都不会编译,我不明白为什么?我已经尝试删除该指令,.intel_syntax但它仍然无法编译。

#include <stdio.h>

int add_two(int, int);

int main(){
     int src = 3;
     int dst = 5;
     printf("summe = %d \n", add_two(src, dst));
     return 0;
}

int add_two(int src, int dst){

    int sum;

    asm (
        ".intel_syntax;"  //switch to intel syntax
        "mov %0, %1;"
        "add %0, %2;"

        ".att_syntax;"  //switch to at&t syntax
        : "=r" (sum) //output
        : "r" (src), "r" …
Run Code Online (Sandbox Code Playgroud)

x86 assembly gcc inline-assembly intel-syntax

5
推荐指数
1
解决办法
4480
查看次数

使用Intel语法从寄存器名称中消除标签歧义

我想知道如何在Intel语法的某些指令中将标签名称与寄存器名称区分开。例如,call rdx通常意味着间接跳转,但是如果我们rdx在同一程序集文件中有标签怎么办?我认为可以将其解释为直接跳转到rdx。是否有任何符号告诉汇编器是哪个?

x86 assembly symbols gnu-assembler intel-syntax

5
推荐指数
1
解决办法
97
查看次数