大会:ecx没有减少

时间:2017-12-07 17:42:31

标签: assembly x86 calling-convention masm32 stdcall

我正在使用MASM并且目前正在实现一个显示大写字母,小字母和ASCII之间的循环

guard let indirectEdges = try? graph.edges.map({ (edge) throws -> IndirectEdge in
    return try edge.indirectEdge()
}) else {throw SimFileError.unimplementedOperation(why: "Don't know how to encode this graph")}
    .
    .
    .

我面临的问题是ECX在循环体中没有减少,并且即使在A-Z%某处%a-z

之后,循环也会永远持续下去

1 个答案:

答案 0 :(得分:2)

您的问题是调用约定。您已将默认约定设置为.model flat, stdcall,这不是问题。这意味着除非另有说明,否则invoke指令将使用stdcall calling convention。 stdcall调用约定包括以下规则:

  
      
  1. 易失性寄存器为:EAX, ECX ,EDX和ST0 - ST7
  2.   
  3. 非易失性寄存器包括:EBX,EBP,ESP,EDI,ESI,CS,DS,ES,FS和GS
  4.   

这意味着你不能假设 EAX ECX EDX 中的值在{{{ 1}} / call。你的循环变量是 ECX ,因此每次调用它们时,很可能会调用invoke ECX 导致无限循环。

最佳选择是使用其中一个非易失性寄存器 EBX EDI ESI (如果使用,则会导致其他问题 EBP ESP )。如果你的注册用完了,你可以:

  • 在调用StdOut之前和之后保存并恢复 ECX 的值,与使用 PUSH在代码中保留 EDX 的方式相同/ POP
  • 将它们存储在基于全局或​​堆栈的内存位置,然后将其还原。
  • 编写代码以避免为循环使用额外的寄存器。