请告诉我一下push和pushl的区别,thx

Bmonkey 2008-05-21 12:32:19
请告诉我一下push和pushl的区别,thx
...全文
2232 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
lywei 2012-08-01
  • 打赏
  • 举报
回复
登录也不让看。。。。。
tomqyp 2009-11-25
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 zmwgreenrain 的回复:]
可能是我上面没说清楚
[/Quote]

上面说的比下面要清楚 :)
brookmill 2008-12-06
  • 打赏
  • 举报
回复
mark
Bmonkey 2008-05-22
  • 打赏
  • 举报
回复
非常清楚,谢谢~~
结贴
zmwgreenrain 2008-05-22
  • 打赏
  • 举报
回复
可能是我上面没说清楚:
当要压栈的对象已经确定(也就是说已经知道是字节、字或者双字),那么使用push就不会产生歧义,也就是说汇编器可以自己判断自己要操作的是什么长度的操作对象;但是当汇编器不能自己判断操作对象长度时,就需要使用pushl之类的指令来指明操作对象长度;
上面的%ebp指的是esp寄存器吧,这是一个32位的寄存器,汇编器是知道这个寄存器存放的是dworld,不需要显式的指明也没有歧义;而 0xfffffff8(%ebp)是使用基址寻址方式指向的一个内存空间,内存是连续的,汇编器不能仅仅根据一个内存地址就判断出那里存放的数据的长度,所以直接这样写就会产生歧义,所以要使用pushl之类的指令来指明要操作的数据的长度;

其实说白了:pushl就相当于intel汇编中的push dworld;

错误例子:"push 01h";nasm汇编器会提示一个警告。
正确例子:Intel格式的"push dworld 01h"或者AT&T格式的"pushl 01h";
dongyi940333 2008-05-21
  • 打赏
  • 举报
回复
学习!!1
zmwgreenrain 2008-05-21
  • 打赏
  • 举报
回复
AT&T汇编中,命令中可以指定操作范围,如pushb是将一个byte压栈,而pushw就是将一个word压栈,同样pushl就是压栈long(也就是双字)。
上面的反汇编中,%esp指的是esp寄存器,已知是双字;而0xfffffff8(%ebp)指的是一个内存空间,所以要用pushl来指明那里存放的是一个双字。
dongyi940333 2008-05-21
  • 打赏
  • 举报
回复
AT&T汇编俺没有学.

0x08048308 <main+0>: push %ebp
。。。。。。。
0x08048329 <main+33>: pushl 0xfffffff8(%ebp)
0x0804832c <main+36>: pushl 0xfffffffc(%ebp)

第一句用push呢?

我想这里压入的是EBP,EBP是32位的所以不用指定操作范围

而第二句压入的是立即数0xfffffff8,所以要指定操作数范围

俺猜的,不对之片请原谅!!!
Bmonkey 2008-05-21
  • 打赏
  • 举报
回复

1.
那如果
0x08048329 <main+33>: pushl 0xfffffff8(%ebp)
0x0804832c <main+36>: pushl 0xfffffffc(%ebp)
中的替换为 push 结果会怎么样?

2.
0x08048308 <main+0>: push %ebp
。。。。。。。
0x08048329 <main+33>: pushl 0xfffffff8(%ebp)
0x0804832c <main+36>: pushl 0xfffffffc(%ebp)
一个程序的反汇编中,为什么会出现push和pushl呢?
%ebp也是内存空间,为什么第一句用push呢?
ncdfly 2008-05-21
  • 打赏
  • 举报
回复
Unix 下的Push 写成Pushl都一样的操作,只是符号不一样罢了
yiyilove97 2008-05-21
  • 打赏
  • 举报
回复
我从没见过pushl..哪位牛人讲解一下
Bmonkey 2008-05-21
  • 打赏
  • 举报
回复
0x08048308 <main+0>: push %ebp
0x08048309 <main+1>: mov %esp,%ebp
0x0804830b <main+3>: sub $0x18,%esp
0x0804830e <main+6>: and $0xfffffff0,%esp
0x08048311 <main+9>: mov $0x0,%eax
0x08048316 <main+14>: sub %eax,%esp
0x08048318 <main+16>: movl $0x4,0xfffffffc(%ebp)
0x0804831f <main+23>: movl $0x6,0xfffffff8(%ebp)
0x08048326 <main+30>: sub $0x8,%esp
0x08048329 <main+33>: pushl 0xfffffff8(%ebp)
0x0804832c <main+36>: pushl 0xfffffffc(%ebp)
0x0804832f <main+39>: call 0x80482f4 <Add>
0x08048334 <main+44>: add $0x10,%esp
0x08048337 <main+47>: mov %eax,0xfffffff4(%ebp)
0x0804833a <main+50>: mov $0x0,%eax
0x0804833f <main+55>: leave
0x08048340 <main+56>: ret
0x08048341 <main+57>: nop
0x08048342 <main+58>: nop
0x08048343 <main+59>: nop


这段程序中,为什么会用push和pushl?
分别使用两者的目的和效果如何?
Linux下AT&T汇编语法格式简介 一、AT&T 格式Linux 汇编语法格式 在 AT&T 汇编格式中,寄存器名要加上 '%' 作为前缀;而在 Intel 汇编格式中,寄存器名不需要加前缀。例如: AT&T 格式 Intel 格式 pushl %eax push eax 在 AT&T 汇编格式中,用 '$' 前缀表示一个立即操作数;而在 Intel 汇编格式中,立即数的表示不用带任何前缀。例如: AT&T 格式 Intel 格式 pushl $1 push 1 AT&T 和 Intel 格式中的源操作数和目标操作数的位置正好相反。在 Intel 汇编格式中,目标操作数在源操作数的左边;而在 AT&T 汇编格式中,目标操作数在源操作数的右边。例如: AT&T 格式 Intel 格式 addl $1, %eax add eax, 1 在 AT&T 汇编格式中,操作数的字长由操作符的最后一个字母决定,后缀'b'、'w'、'l'分别表示操作数为字节(byte,8 比特)、字(word,16 比特)和长字(long,32比特);而在 Intel 汇编格式中,操作数的字长是用 "byte ptr" 和 "word ptr" 等前缀来表示的。例如: AT&T 格式 Intel 格式 movb val, %al mov al, byte ptr val 在 AT&T 汇编格式中,绝对转移和调用指令(jump/call)的操作数前要加上'*'作为前缀,而在 Intel 格式中则不需要。 远程转移指令和远程子调用指令的操作码,在 AT&T 汇编格式中为 "ljump" 和 "lcall",而在 Intel 汇编格式中则为 "jmp far" 和 "call far",即: AT&T 格式 Intel 格式

21,459

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧