linux nasm assembly print all numbers from zero to 100

后端 未结 3 1104
深忆病人
深忆病人 2021-01-28 15:23

I am writing a program to print out all the numbers from zero to 100. The only reason I am doing this is to test out printing out multiple digit numbers.

The problem th

3条回答
  •  Happy的楠姐
    2021-01-28 16:00

    EDIT: it's not an "error" per se, but just misdirection for the casual reader to access a counter and strlen as one byte variables and in other places compare the contents to 32-bit variables...

    add BYTE[ecx], NUL

    this perhaps adds NUL terminator to ecx, but I suppose it should append the terminator. That could happen at place [ecx+1].

    Anyway the handling of the variables and pointers is very unconventional in your code...

    First: the kernel functions that 'output' stuff, assume that ecx contains the address of a string. There isn't a string allocated anywhere. If the string would just fit into the eight bytes reserved to counter at counter resb 8, and the counter would contain characters: '1','3','\0' then the approach would work. And this reveals the second thing: printf deals with strings, which encode single digits 0-9 to values 48-57. Space e.g. in this ASCII system encodes to 32 (decimal) while \NUL is ascii zero.

    So, what is needed:

    • option 1
      Initialize your counter to a string

      counter db '0','0','0','0','0','0','0','1'  
      length  dq 1
      

      Ascii zero is not needed to terminate the string, because as I understood, it's given to the print function

      Then one can give the real pointer to the string as

      lea ecx, counter     // get the address of counter string
      add ecx, 7           // this is the last character
      

      Also one can increase the counter as a string one digit at a time:

      loop:  
      mov al,[ecx]   // assuming ecx still points to last character  
      inc al  
      mov [ecx],al  
      cmp al, '9'  
      jle string ok  
      mov al, '0'  
      mov [ecx],al  
      dec ecx  
      jmp loop  
      ok:     // here the counter has been increased correctly  
      
    • option 2

      Increase the counter as a 32-bit integer Convert the integer to string one digit at a time with the following algorithm:

      digits = 0;  
      string_ptr = &my_string[32];  // move barely outside the string  
      do {  
        last_digit = a % 10 + '0';      // calculate the last digit and convert to ASCII
        a = a / 10;  
        *--string_ptr = last_digit;     // write the last digit
        digits++;                       // count the number of digits  
      } while (a);  
      // because we predecrement string_ptr, that value also contains the exact  
      // start of the first character in the printable string. And digits contains the length.
      

    To produce some good looking result, one has to still add line feeds. That can be handled separately or just appended to the original string -- and ensure they are never written over, so they can be used in all cases.

提交回复
热议问题