- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
最近我在看汇编 IA32,我做了一个简单的玩具示例:
#include <stdio.h>
int array[10];
int i = 0;
int sum = 0;
int main(void)
{
for (i = 0; i < 10; i++)
{
array[i] = i;
sum += array[i];
}
printf("SUM = %d\n",sum);
return 0;
}
是的,我知道不太推荐使用全局变量。我在没有优化的情况下编译了上面的代码并使用了标志 -s,我得到了这个程序集:
main:
...
movl $0, %eax
subl %eax, %esp
movl $0, i
.L2:
cmpl $9, i
jle .L5
jmp .L3
.L5:
movl i, %edx
movl i, %eax
movl %eax, array(,%edx,4)
movl i, %eax
movl array(,%eax,4), %eax
addl %eax, sum
incl i
jmp .L2
没什么花哨的,也很容易理解,这是一个普通的while循环。然后我用 -O2 编译了相同的代码并得到了以下程序集:
main:
...
xorl %eax, %eax
movl $0, i
movl $1, %edx
.p2align 2,,3
.L6:
movl sum, %ecx
addl %eax, %ecx
movl %eax, array-4(,%edx,4)
movl %edx, %eax
incl %edx
cmpl $9, %eax
movl %ecx, sum
movl %eax, i
jle .L6
subl $8, %esp
pushl %ecx
pushl $.LC0
call printf
xorl %eax, %eax
leave
ret
在这种情况下,它转换为 do while 类型的循环。从上面的程序集中我不明白的是为什么 "movl $1, %edx" 然后是 "movl %eax, array-4(,%edx,4)" .
%edx 以 1 而不是 0 开始,然后在访问数组时它从初始位置开始 -4(4 字节 = 整数)。为什么不简单呢?
movl $0, %edx
...
array (,%edx,4)
如果您需要一直执行 -4,则不要从 1 开始。
出于教育原因,我正在使用“GCC: (GNU) 3.2.3 20030502 (Red Hat Linux 3.2.3-24)”来生成易于理解的程序集。
最佳答案
我想我终于明白了,我测试了:
...
int main(void)
{
for (i = 0; i < 10; i+=2)
{
...
}
}
得到:
movl $2, %edx
和 for (i = 0; i < 10; i +=3) 并得到:
movl $3, %edx
最后用 (i = 1; i < 10; i +=3) 得到:
movl $4, %edx
因此,编译器正在初始化 %edx = i (i 的初始值) + incrementStep;
关于c - 为什么 "movl $1, %edx"而不是 "movl $0, %edx",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29780215/
最近我在看汇编 IA32,我做了一个简单的玩具示例: #include int array[10]; int i = 0; int sum = 0; int main(void) { for
我正在尝试了解内存间接寻址在使用 AT&T 语法的汇编语言中究竟是如何工作的。 movl (%eax), %ebx movl %eax, (%ebx) 这是一个类似的问题,解释了 memory ind
这是调用函数后的部分代码。 movl 12(%ebp),%ecx movl 8(%ebp),%esi movl (%esi,%ebx,4),%edx 这是对应的 C 函数: vo
'$' 后跟一个标识符是什么意思? x86 汇编,AT&T 语法。 最佳答案 在 AT&T 语法中 $意味着将后面的内容视为立即常量而不是内存地址。换句话说, movl $_start, %eax 加
对于这段 C 代码: uint64_t roundUp(uint64_t value, uint32_t blockSize) { return (value + blockSize - 1)
这个问题在这里已经有了答案: Using LEA on values that aren't addresses / pointers? (3 个回答) 4年前关闭。 leal(%eax,%ecx,4
这是 AT&T Syntax 中的一段汇编代码。 int foo_array[64*1024] __attribute__ ((aligned (8192))); void foo() {
我已经用汇编编写了一个程序,输入后: as -32 maximum.s -o maximum.o ld -m elf_i386 maximum.o -o maximum ./maximum 它显示段错
我有一些用 gcc 编译的 C 代码: int main() { int x = 1; printf("%d\n",x); return 0; } 我已经通过 gdb 7.9.
我试图理解一些汇编代码: movl $244, %eax movl %1, %%ebx 第一个表示将数字244放入寄存器eax,但是第二个是什么意思?在此先感谢您的帮助 P.S see the dif
语境: 在 64 位 linux 上学习 GAS 汇编。 许多教程是针对 32 位汇编的。 很难通过 x86_64 程序集进行丛林攻击。 题: 当我用gcc编译c程序时,我仍然看到一些%eax和 mo
这是一本旧书上的一个小函数: unsigned long f() { __asm__("movl %eax,%esp"); } 函数解释为获取堆栈点,但似乎不是。它实际上获取了一个比我的帧地址低
将这 3 条指令作为 movl 指令的源是什么意思? (%esi, %ecx, 4) 最佳答案 意思是: 计算地址 = (ESI + ECX * 4)。从该内存地址的 32 位值将值读入 EAX。 来
是cmpl相当于movl的指令+ 比较。如果是这样,黑白有什么区别:(1) LBB1_2: cmpl $0, _data_ready(%rip) je LBB1_2 和:(2
此程序(来自 Jonathan Bartlett 的 Programming From the Ground Up )使用 .long 循环遍历存储在内存中的所有数字,并在程序完成时将最大的数字放入
我在 GAS 源代码中定义了一个 MACRO。但是不是gcc编译的。 下面是我定义的MACRO。 #define MSGSCHEDULE0(index) \ movl (index*4)(%r
这两条指令在gcc为x86机器生成的汇编代码中产生了什么影响: push %ebp movl %esp, %ebp 最佳答案 unwind的解释是字面上的事实(尽管有一个较小的方向性错误),但没有解释
我正在学习如何在汇编中编程,我有一个澄清问题。在我的书中,它充分说明了将正确的后缀与命令结合使用的重要性。然而,在类里面老师只使用了“movl”操作数。我的老师这样做是为了简单起见还是“movb”和“
我正在学习如何在汇编中编程,我有一个澄清问题。在我的书中,它充分说明了将正确的后缀与命令结合使用的重要性。然而,在类里面老师只使用了“movl”操作数。我的老师这样做是为了简单起见还是“movb”和“
我正在研究 GCC 生成的汇编代码。但是我不明白: movl $0x2d, 0x4(%esp) 在第二个操作数中,0x4 代表什么?偏移地址?寄存器EAX有什么用? 最佳答案 movl $0x2d,
我是一名优秀的程序员,十分优秀!