测试汇编中的程序是否正常工作

Testing if a program in assembly is working correctly

我是汇编的新手,我正在尝试为 x86 构建一个非常简单的程序,将值放入 EAX:

(Nothing?) if EBX can be divided by 2^n with n>3

1 if EBX can be divided by 2^3 -> 8

2 if EBX can be divided by 2^2 -> 4

3 if EBX can be divided by 2^1 -> 2

0 if EBX is an odd number

所以我构建了这个程序并对其进行了测试,一切运行良好,但我不知道如何查看它是否真的按照我想要的方式执行。我找不到任何方法来输出注册表的当前值,并且互联网的丰富知识只能为我提供部分答案,这些答案并没有让我走得太远。

我主要担心的是我不确定 ret 语句 returns 到 _main 函数,还是只是 "breaks" 执行。后者是我想要的。那么有没有办法让我检查我的程序是否正常工作?

section .text
    global _main

_main:
    MOV EAX, EBX
    MOV ECX, 16
    DIV ECX
    CMP DX, 0    ;Op=word (1,0,0,0,0), AX := DX:AX/Op, DX -> rest
    JE end0      ;If number%16 == 0
    MOV EAX, EBX
    MOV ECX, 8
    DIV ECX
    CMP DX, 0    ;Op=word (1,0,0,0), AX := DX:AX/Op, DX -> rest
    JE end8      ;If number%8 == 0
    MOV EAX, EBX
    MOV ECX, 4
    DIV ECX
    CMP DX, 0    ;Op=word (1,0,0), AX := DX:AX/Op, DX -> rest
    JE end4      ;If number%4 == 0
    MOV EAX, EBX
    MOV ECX, 2
    DIV ECX
    CMP DX, 0    ;Op=word (1,0), AX := DX:AX/Op, DX -> rest
    JE end2      ;If number%2 == 0
    JMP end1     ;

end8:
    MOV EAX, 3
    ret

end4:
    MOV EAX, 2
    ret

end2:
    MOV EAX, 1
    ret

end1:
    MOV EAX, 0
    ret

end0:
    ret

您可以使用调试器单步执行代码并在每一步检查寄存器和内存。

关于你关于ret的问题:它是call的对立面,粗略地说它会在最近的call之后继续。 (这是一个简化的视图。)请注意,您使用简单的条件跳转,例如 je end0,因此 end0 中的 ret 不会 return 到该位置。相反,它将退出您的 _main 并继续调用它的人,这大概是 C 启动代码。实际上它退出了你的_main。据我所知,这正是您想要的。

PS:您使用的 DIV 是错误的,它只是偶然起作用。它隐含地使用 EDX 作为被除数的高 32 字,因此对于 32 位无符号除法,您应该始终将其归零。甚至您的评论也这么说,尽管那描述了 16 位版本的操作。

另请注意,要检查 2 的幂的整除性,通常使用按位运算,而不是除法。