assembly 在汇编语言中,%在寄存器名称上是什么意思?

yhqotfr8  于 2023-06-06  发布在  其他
关注(0)|答案(2)|浏览(258)

我尝试用GCC -S选项将C语言代码转换和解释为汇编语言。push %rbppush rbp的区别是什么?

efzxgjgh

efzxgjgh1#

你给出的两个语句做的是同样的事情,主要的区别在于语法。
X86有两种主要的语法约定,Intel约定和AT&T约定。
有关详细信息,请参见语法比较。

**[UPD:]**以防万一,这里重复语法信息:

| | 美国电话电报公司|英特尔|
| - -----|- -----|- -----|
|参数顺序| 源在目的地之前。movl $5, %eax|目标在源之前。mov eax, 5|
|参数大小| 助记符的后缀是一个字母,表示操作数的大小:q表示qword,l表示long(dword),w表示word,B表示byte。addl $4, %esp|从使用的寄存器名称派生(例如:raxeaxaxal分别暗示qlwB)。add esp, 4|
| Sigils| Immediate values前缀为**$,寄存器前缀为%。|汇编程序自动检测符号的类型;即它们是寄存器、常量还是其它。|
|有效地址| DISP(BASE,INDEX,SCALE)的一般语法。movl mem_addr(%ebx,%ecx,4), %eax|方括号中的算术表达式;另外,如果不能从操作数确定大小,则必须使用大小关键字,如
byte**、worddwordmov eax, [ebx + ecx*4 + mem_addr]|

5lwkijsr

5lwkijsr2#

在AT&T语法中,push rbp将是一个内存操作数的推送,符号名为rbp,就像你编译了一些使用long rbp;作为全局变量的C代码一样。
rbp没有%,所以汇编器知道你没有引用同名的寄存器;这就是AT&T语法消除这种情况歧义的方法。如果你确实需要寄存器,你 * 必须 * 像%rbp一样使用%

rbp是绝对寻址模式;通常你会使用pushq rbp(%rip),如果你真的想推一个全局的内容。具有任何其他寻址模式的推式存储器看起来像pushq (%rdi, %rsi, 8)。在32位代码中,通常使用纯符号名访问全局变量,如mov foo, %eax从一个变量加载。
但更有可能的是,你指的push rbppush %rbp的英特尔语法版本,像普通人一样推动寄存器。

gcc -masm=intel将使用Intel语法,默认为-masm=att。挑你觉得容易读的。参见How to remove "noise" from GCC/clang assembly output?

有关语法差异的更多详细信息,请参阅@hidefromkgb的答案,以及:

相关问题