有人可以帮我解决这个程序集:首先打印数字1到100.然后按照儿童计数游戏Fizz的规则:每当数字可以被5整除时,或包含 数字5,用“Fizz”一词代替数字。到目前为止,这是我的计划:
extern printf
section .data
msg db "Hello, world!",0xa
len equ $ - msg
fmt: db "a=%d, eax=%d", 10, 0 ; The printf format, "\n",'0'
section .text
global main
main:
L1:
mov eax,1
push eax
call printf
cmp eax,100
jae end
inc eax
end:
答案 0 :(得分:3)
我不打算给你一个完整的答案,因为这似乎是作业。我会提供足够的帮助你。以下代码将从1到100进行计数:
extern printf
section .data
fmt: db "number = %d", 10, 0 ; printf format string
section .text
global main
main:
push ebx ; EBX is callee saved so we need to save it so that it
; can be restored when we RETurn from main
mov ebx, 1 ; ebx = 1 (counter)
L1:
push ebx ; 2nd parameter is our number(counter) to print
push fmt ; 1st parameter is the address of the format string
call printf
add sp, 8 ; We pushed 8 bytes prior to printf call, we must adjust the stack
; by effectively removing those bytes.
inc ebx ; counter += 1
cmp ebx,100
jle L1 ; If counter is <= 100 go back and print again
end:
xor eax,eax ; Return 0 when our program exits
pop ebx ; Restore EBX before exiting main per calling convention
ret ; RETurn from main will cause program to gracefully exit
; because we are linked to the C runtime code and main was
; called by that C runtime code when our program started.
代码中的主要更改。我们使用printf使用正确的格式字符串显示数字。我把计数器放在 EBX 中,因为您必须知道 EAX , ECX 和 EDX 不会被保留使用CDECL调用约定的函数调用:
在cdecl中,子程序参数在堆栈上传递。整数值和存储器地址在EAX寄存器中返回,ST0 x87寄存器中的浮点值。 注册EAX,ECX和EDX被呼叫者保存,其余的被呼叫者保存。
[剪断]
调用程序在函数调用返回后清理堆栈。
在进行 CDECL 函数调用之后,我们必须恢复堆栈指针。我们将2 DWORD s(总共8个字节)作为参数推送到printf
因此我们必须在堆栈指针中添加8到有效当函数删除它们时回报。
突出显示的句子很重要。为了简化我使用 EBX 的事情,因为它的值在函数调用中保留,我们不必围绕我们进行的函数调用保存和恢复它(如printf
)。 / p>
由于使用 CDECL 调用约定将main
称为 C 函数,我们必须保留所有被调用者寄存器(我们的函数必须保留的寄存器),以便我们不会在调用main
的 C 库代码中导致未定义的行为。 EBX 是我们修改过的被调用者保存的寄存器,因此我们在函数周围使用 PUSH / POP ,以便 EBX 在我们的main
函数返回时保留。
该程序必须链接到 C 库。最简单的方法是使用 GCC 进行链接。编译和链接阶段可能如下所示:
nasm -f elf32 count100.asm -o count100.o
gcc -m32 count100.o -o count100
这应该将您的代码汇编并链接到一个名为count100
的32位程序,该程序可以使用此命令执行:
./count100
我将剩下的任务留给你了。
示例中的汇编代码与 C 中的代码相同:
#include <stdio.h>
int main()
{
int counter = 1;
do {
printf ("number = %d\n", counter);
} while (++counter <= 100);
return 0;
}