+ -
当前位置:首页 → 问答吧 → 初学汇编遇到的两个个问题。

初学汇编遇到的两个个问题。

时间:2011-10-06

来源:互联网

.386
.model flat,stdcall
option casemap:none
includelib msvcrt.lib
printf PROTO C:DWORD, :vararg
system PROTO C:DWORD
.data
data1 BYTE "RESULT IS %d",0aH,0
data2 BYTE "pause",0aH,0
.code

func1 proc;三个数相加
  PUSH EBP
  MOV EBP,ESP
  MOV EAX,[EBP+8]
  ADD EAX,[EBP+12]
  ADD EAX,[EBP+16]
  POP EBP
  RET
func1 ENDP
start:
  PUSH 1
  PUSH 2
  PUSH 3
  CALL func1
  INVOKE printf,OFFSET data1,EAX;这里输出6对了
  ADD ESP,12;问题1:这里为什么可以要,也可以不要?这样堆栈会平衡?结果会对?
  PUSH EAX
  PUSH 7
  PUSH 8
  CALL func1
  ADD ESP,12
  INVOKE printf,OFFSET data1,EAX;问题2:这里的直为什么是27不是21。。
  INVOKE system,OFFSET data2
  RET
end start



问题3:MOV BYTE PTR[EBX-ESI],0 这句哪里错了
不好意思分不多了


最后,问一下

作者: groundhappy   发布时间: 2011-10-06

问题1: 对于 printf() 这样的参数个数不定的函数来说,必须要的,因为 printf() 函数自己无法固定地通过 ret ?? 指令来进行堆栈平衡,只有调用者来进行这个操作。对于其它参数个数固定的函数,就是由函数自己来进行堆栈平衡的,调用者无须任何操作,所以就不要了。自己写的函数,最好也遵循这个规则;一来规范统一,易于管理和移植;二来性能方面也有些优势。
问题2:调用 printf() 改变了 eax 的内容?调试下就知道原因了。对函数而言,eax/edx/ecx 是可能被其改变的,所以,如果需要在调用前后保持、继续使用原来的内容,就要自己进行保存和恢复的操作。
问题3: 不支持这样的寻址模式。寄存器组合,只有加法,没有减法。如 mov byte ptr [ebx+esi],0 就是可以的。

作者: zara   发布时间: 2011-10-08