2015-01-14 93 views
0

我想读取用户的3个数字,我把它们存储在一个数组,然后我告诉他们在NASM使用保罗·卡特功能这里是我的代码:打印整数NASM

%include "asm_io.inc" 

SECTION .bss 

tab resb 3 

SECTION .data 
msg db "Un nombre :",10 

SECTION .text 
global main 
     main: 
    mov esi,tab 
    xor ecx,ecx 
get_data: 
    mov eax,msg 
    call print_string 
    call read_int 
    mov [esi+ecx],eax 
    inc ecx 
    cmp ecx,3 
    jne get_data 
    call print_nl 
    xor ecx,ecx 
    mov edi,tab 
print_data: 
    mov eax,[edi+ecx] 
    call print_int 
    inc ecx 
    cmp ecx,3 
    jne print_data 






    mov eax,1 ; exit code 
    int 0x80 ; call exit 

的问题是即不执行print_data循环并退出。

+0

你只保留3个字节'tab'。如果你想要3个dword,你应该使用'resd 3'而不是'resb 3',并且你应该在每次迭代结束时将ecx增加4而不是1。另外,我没有介绍'asm_io.inc'中的函数是如何实现的,但'ecx'通常是一个_caller-saved_寄存器,这意味着您不应该依赖它来保持函数调用的值。你的'msg'字符串也似乎缺少一个NUL终止字节。 – Michael

+0

我已经修改了程序,正如你所说的那样,期望'ecx'寄存器不被这些函数使用,但它仍然跳过该循环。 –

+0

它不能跳过循环。但也许它不会打印你想看到的结果。顺便说一下,读取asm代码非常困难,没有来自编写它的人的评论。当你在代码中添加更改时,更新你问题中的代码。除此之外,你需要描述你所调用的功能实际上是做什么的。 – Blechdose

回答

0

只是要清楚。这些变化是你做的吗?即使ECX寄存器不被用作特定功能的输入或输出,它仍可能在内部使用。这就是迈克尔的意思与“ECX通常是来电者保存的”

%include "asm_io.inc" 

SECTION .bss 

tab resd 3 

SECTION .data 
msg db "Un nombre :",10,0 

SECTION .text 
global main 
main: 
mov edi,tab 
xor ecx,ecx 
get_data: 
push ecx 
mov eax,msg 
call print_string 
call read_int 
mov [edi+ecx*4],eax 
pop ecx 
inc ecx 
cmp ecx,3 
jne get_data 
call print_nl 
mov esi,tab 
xor ecx,ecx 
print_data: 
push ecx 
mov eax,[esi+ecx*4] 
call print_int 
pop ecx 
inc ecx 
cmp ecx,3 
jne print_data 

mov eax,1 ; exit code 
int 0x80 ; call exit 
+0

我已经完成了所有这些修改,并试图推动所有寄存器,即使那些女巫没有在循环中使用,但我仍然有同样的问题n,顺便说一下,如果你看看保罗卡特文档(他书),你会发现他在调用函数之前不会推送任何寄存器。 –

+0

段寄存器设置是否正确? **书中说“本文中的早期程序都将从图1.6中的简单C驱动程序开始,它只是调用另一个名为asm main的函数,这实际上是一个用汇编语言编写的例程,首先,这可以让C系统设置程序在保护模式下正确运行,所有段和它们对应的段寄存器将由C初始化。 – Fifoernik