我正在努力教自己大会(出于好奇心和学习兴趣),并开发了一些从5到0的代码。这就是它的全部。我想知道以下代码是否有效?
.386
.model flat, stdcall
.data
i dd 5
.code
main:
MOV cx, 5
lp:
LOOP lp
MOVZX eax, cx
RET
END main
请注意,我使用MOVZX
指令将cx
的值复制到eax
(我的编译器用来返回的内容)。
我这样做是因为如果我只使用MOV
,我的程序将无法汇编。使用MOVZX
是否可取?或者我应该采取更有效的方式吗?
您还会在我的代码中注意到我i dd 5
我的原始计划是MOV cx, i
但我的编译器在尝试时拒绝汇编。 (MOVSX
产生相同的结果)。所以我的第二个问题是,如何将i
的值移到cx
寄存器中?
答案 0 :(得分:1)
如果您正在编写32位目标,则使用ecx
寄存器而不是16位cx
寄存器。然后,您将能够在没有汇编程序抱怨操作数大小的情况下使用mov eax, ecx
。此外,loop
指令隐式使用ecx
,因此您需要确保整个寄存器初始化为5,而不仅仅是低16位。
使用ecx
后,指令mov ecx, i
可能会有效 - 但您没有说出在尝试时遇到的实际错误。
答案 1 :(得分:1)
你的代码效率不高,没有。 LOOP指令很旧并且很少使用,因为它不像简单地手动递减那样执行。
您可以通过将寄存器与自身进行异或来归零,然后您可以使用立即ADD将数字加载到其中。我没有太多使用汇编,所以我没有完整的语法,不幸的是不能发布一个例子。
答案 2 :(得分:1)
这是一个类似于你的C例子:
#include <stdio.h>
int i = 5;
int
main (int argc, char *argv[])
{
while (--i >= 0)
;
return 0;
}
这是Visual Studio汇编程序输出(cl / Fa):
.386P
include listing.inc
if @Version gt 510
.model FLAT
else
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
_DATA SEGMENT DWORD USE32 PUBLIC 'DATA'
_DATA ENDS
CONST SEGMENT DWORD USE32 PUBLIC 'CONST'
CONST ENDS
_BSS SEGMENT DWORD USE32 PUBLIC 'BSS'
_BSS ENDS
_TLS SEGMENT DWORD USE32 PUBLIC 'TLS'
_TLS ENDS
FLAT GROUP _DATA, CONST, _BSS
ASSUME CS: FLAT, DS: FLAT, SS: FLAT
endif
PUBLIC _i
_DATA SEGMENT
_i DD 05H
_DATA ENDS
PUBLIC _main
_TEXT SEGMENT
_main PROC NEAR
; File x.c
; Line 7
push ebp
mov ebp, esp
$L342:
; Line 8
mov eax, DWORD PTR _i
sub eax, 1
mov DWORD PTR _i, eax
cmp DWORD PTR _i, 0
jl SHORT $L343
; Line 9
jmp SHORT $L342
$L343:
; Line 10
xor eax, eax
; Line 11
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END