2012-02-04 70 views
0

问题由汇编程序组成,该程序从C程序获取输入并将其除以数字,然后将余数返回给C程序作为字符串打印。将整数转换为NASM中的字符串

这里是我的两个代码:

#include <stdio.h> 
#include <stdlib.h> 

int main() 
{ 
int i; 
char *str; 
str = malloc(1<<9); 

printf("Enter a number: "); 
scanf ("%d", &i); 
printf("Number: %i\n", i); 
str=int2string(i); 
printf("Number as string is: %s\n", str); 

return 0; 

} 

ASM =

%include "asm_io.inc" 

segment .data 

segment .bss 

buffer resd 4 

segment .text 
    global int2string 
int2string: 
    enter 0,0    ; setup routine 
    pusha 
    mov edx, 0 

    mov eax, [ebp+8]  ; eax contains input value of int2string 

    mov ebx, 10  ; sets ebx to value of 10 
    div ebx   ; eax = eax/ebx 

    call print_int  ; prints eax = quotient 
    call print_nl  ; next line 

    mov eax, edx  ; store edx (remainder) in eax 

    call print_int  ; print remainder 
    call print_nl  ; next line 

    add eax, 48  ; convert result into ASCII character 

    popa 
    mov dword[buffer], eax ; move ASCII character (if I replace eax with 48-57 
          ; it prints 0-9 correctly) 
    mov eax, buffer  ; move buffer value to eax 
    leave      
    ret 

我的理解是,数字0-9的ASCII码是从48-57范围内,但如果我不要将数字明确地放在缓冲区移动中,那么输出是垃圾或分段错误。

我在这里丢失了什么(eax值为2 + 48,应该是ASCII(50)='2')?

+0

RESD声明未初始化的存储空间,我的nasm是生锈的,但我看不到你null终止你生成的字符串。 – 2012-02-04 23:58:46

+0

@JoachimIsaksson,我原本以为但是,因为你存储的是一个32位的寄存器,其值为零到九(字符,所以48到57整数),它将被存储为val/0/0/0。自动空终止,虽然可能只是一个无用的副作用:-) – paxdiablo 2012-02-05 00:04:00

+0

在c程序描述中,它声明'str'字符数组大小为20,那么我将如何去初始化存储空间到该规范? – user1074249 2012-02-05 00:06:26

回答

0

很可能print_intprint_nl可能不会保留eax的值(尤其是因为常见调用约定是返回该寄存器中函数的结果)。如果你的第二个电话print_int打印出正确的值但字符错误,那么这是一个明显的可能性。

为一个简单的测试/修复方法是:

call print_int  ; print remainder 
call print_nl  ; next line 

到:

push eax 
call print_int  ; print remainder 
call print_nl  ; next line 
pop eax 

除此之外,它看起来。我所能建议的只是单步执行代码,看看它出错的地方。

+0

原来,eax没有存储该值(至少我认为?),但我改变了存储位置到ebx,然后移动到缓冲区然后到eax,似乎现在正在工作,感谢输入 – user1074249 2012-02-05 00:13:37

+0

@ user1074249,'eax' _does_存储'div'和'edx'的结果reaminder:(atomic'eax < - edx:eax/,edx < - edx:eax%')所以,如果它不是你所期望的,那很可能是函数调用破坏'eax'。 – paxdiablo 2012-02-05 00:19:16

+0

我有另一个问题,试图进行除法计算两次:(14 div 10 =商1,余数4 => 1 div 10 =商0,余1)但当我重新计算div ebx,我得到了一些完全关闭(以百万计) – user1074249 2012-02-05 05:18:15