addressing-mode相关内容
由于这方面的网络资源很少,为了将来搜索的方便,我将首先列出 IA-32 汇编语言 (NASM) 的地址模式,然后跟进一个快速问题. 注册地址 mov eax, ebx:将 ebx 中的内容复制到 eax 中 mov esi, var:将 var 的地址(比如 0x0040120e)复制到 esi 中 立即寻址(第二个操作数是立即数) mov bx, 20: 16位寄存器bx获取实
..
我已经用谷歌搜索了很多,但无法弄清楚括号 () 的含义.另外,我看到一些语法为 movl 8(%ebp), %eax 有人可以给我推荐一些好的参考资料吗?我无法在 Google 的前 20 个结果中找到任何结果. 解决方案 %eax 是注册 EAX;(%eax) 是地址包含在寄存器EAX中的内存位置;8(%eax) 是地址为 EAX 值加 8 的内存位置.
..
(register1, register2, 4) 在 AT&T 汇编中是什么意思? 例如: cmp %eax, (%esi, %ebx, 4) 解决方案 完整的 AT&T 基址/索引寄存器语法是: offset(base, index, multiplier) 你的 offset 字段是 0,所以你只有 (base, index, multiplier) 部分.在您的情况下,您将
..
关于下面的小代码,在另一篇关于结构大小和正确对齐数据的可能性的文章中进行了说明: 结构{字符数据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
..
一直从事装配作业,并且在大多数情况下,我对装配非常了解.或者至少对于这项任务来说足够好.但是这个 mov 声明让我很不舒服.如果有人能解释一下这个 mov 语句是如何操作寄存器值的,我将不胜感激. mov (%ebx,%eax,4),%eax 附言我无法通过基本搜索找到这种特定类型的 mov 语句,因此如果我错过了它并重新提问,我深表歉意. 解决方案 AT&T程序集中完整的内存
..
rax 是得到偏移量加上这条指令的地址,还是下一条?从微码的角度来看,如果答案是下一条指令可能会更容易. 解决方案 下一个.这是 x86 上的一般规则(另见分支). 在英特尔手册第 2 卷第 2.2.1.6 节 RIP 相对寻址中: 一种新的寻址形式,RIP-relative(相对指令指针)寻址,是在 64 位模式下实现的.下一条指令的 64 位 RIP 加上位移形成有效地址.
..
这个指令有什么作用? mov (%r11,%r12,1), %edx 解决方案 查看这里.它说 在 AT&T 语法中,内存是引用方式如下, segment-override:signed-offset(base,index,scale) 页面下方有一些示例.我觉得这是最好的: GAS 内存操作数 NASM 内存操作数------------------ -------------
..
Intel 和 AT&T 语法中内存寻址的一般形式如下: [base + index*scale + disp]显示(基础,索引,比例) 我的问题如下: base 和 index 可以是任意寄存器吗? scale 可以取什么值,是 1、2、4 和 8(1 是默认值)? index 和 disp 是否可以互换(唯一的区别是 index 是一个寄存器,而 disp 是立即值)? 解
..
考虑 x64 Intel 程序集中的以下变量引用,其中变量 a 在 .data 部分声明: mov eax, dword ptr [rip + _a] 我无法理解此变量引用的工作原理.由于a是变量运行时地址对应的符号(带重定位),如何[rip + _a]解引用a?确实,rip保存的是当前指令的地址,它是一个很大的正整数,所以加法会导致a的地址不正确? 相反,如果我使用 x86 语法(非常
..
我对 x86-64 二进制编码很陌生.我正在尝试修复一些旧的“汇编"代码. 无论如何,我正在尝试做这样的事情(英特尔语法): mov [rbp+rcx], al 汇编器当前正在生成: 88 04 0D 但这似乎不是一个有效的指令.如果我将 SIB 字节中的基址从 rbp 更改为其他一些寄存器,则它可以正常工作.另一种使其工作的方法是添加一个一字节的零位移(88 44 0D 00).这
..
我无法指向地址并在我的情况下写入大小为字节的变量.这给了我错误“错误:无效的有效地址": mov byte[AX], byte 0x0 经过一些跟踪和错误后,我用 EAX 进行了相同的测试.这编译得很好: mov byte[EAX], byte 0x0 我在这里遗漏了什么? 解决方案 [AX] 是无效的内存操作数规范. 有效的 16 位是: [常数][BX][SI][DI]
..
我正在尝试将“main"的地址加载到 GNU 汇编器中的寄存器 (R10) 中.我没办法.这是我所拥有的和我收到的错误消息. 主要:主要,%r10 我也尝试了以下语法(这次使用 mov) 主要:movq $main, %r10 对于以上两种情况,我都收到以下错误: /usr/bin/ld:/tmp/ccxZ8pWr.o: 重定位 R_X86_64_32S 对符号 `main' 不能在创建
..
我有一个内存位置,其中包含一个我想与另一个字符进行比较的字符(它不在堆栈的顶部,所以我不能只是 pop 它).如何引用内存位置的内容以便进行比较? 基本上我如何在语法上做到这一点. 解决方案 有关寻址模式(16/32/64 位)的更多讨论,请参见 Agner Fog 的“优化组装"指南,第 3.3 节.该指南比此答案提供了更多关于符号和/或 32 位位置无关代码等重定位的详细信息.
..
快速提问.此代码不会编译: mov eax, dword [rbx+rsi*5] 我不指望它,并解释说 mov 和乘法是两种不同的 CPU 操作.可以实现的唯一原因是通过位移. 但是,这确实可以编译: mov eax, dword [lst+rsi*5] “lst"是一个变量数组.在上下文中使用时它也会产生输出(因此代码编译和运行).为什么会这样? yasm -Worphan-la
..
在 8086 中这种结构是正确的: mov bh,[bx] 但这不正确: mov bh,[cx] 我不知道为什么.我认为通用寄存器(AX、BX、CX、DX、SP、BP、SI 和 DI)是我们可以用于任何目的的寄存器,BX 用于基地址或 CX 用于计数器的声明只是一个约定,它们根本没有区别.但似乎我错了.你能解释一下原因吗?这些寄存器之间的确切区别是什么?(例如为什么我不能将基地址保存在 c
..
如果我说: lea (%eax,%eax,2), %edx 有人告诉我,这基本上意味着: edx = eax + eax * 2 这个格式是如何工作的? 我想这会引出第二个问题.如果我有这样的事情: add -0x4(%esi, %ebx, 4), %eax 我知道第一个操作数被添加到第二个操作数,然后存储在第二个操作数中,但同样,我不明白的是第一个操作数的符号.另一个例子是如果
..
所有这些东西之间有什么区别:平面地址,基址地址,线性地址,有效地址,物理地址,有效地址计算??? 解决方案 80x86 既有分段又有分页;其中虚拟地址(该软件使用)被转换为物理地址(该硬件如内存控制器)使用.完整转换: 第一个 CPU 确定有效地址/偏移量(例如,对于像“mov eax,[eax+ebx*4+99]"这样的指令,CPU计算结果"eax+ebx*4+99") 然后
..
假设以下值存储在指定的内存地址和寄存器中: 地址值寄存器值0x100 0xFF %eax 0x1000x104 0xAB %ecx 0x10x108 0x13 %edx 0x30x10C 0x11填写下表,显示指定操作数的值:Operand Value//本章末尾的解决方案%eax _____//0x1000x104 _____//0xAB$0x108 _____//0x108(%eax) __
..
LEA 指令是否支持负位移? mov rax, 1lea rsi, [rsp - rax] 当我在 asm 文件中使用上述代码时,出现错误: $ nasm -f macho64 test.asm$ 错误:无效的有效地址 我知道我们可以在 C 中做这样的指针运算: void foo(char *a, size_t b) {*(a - b) = 1;} 然后我假设: lea rsi, [
..
是否可以在 x86-64 的索引寻址模式中使用 8 位寄存器(al, ah, bl, bh, r8b)?例如: mov ecx, [rsi + bl]mov edx, [rdx + dh * 2] 特别是,这将允许您使用寄存器的底部 8 位作为 0-255 偏移量,这对某些内核很有用. 我翻遍了英特尔手册,他们没有明确说明这个问题,但他们给出的所有示例都只有 32 位或 64 位基址和索
..