-1

I think my loop is wrong and the r10 register is not printing to the screen.

section .data

section .bss
know resd  16

section .text
   global _start         

    
_start:  

REDO:
   inc r10

   mov eax, 4
   mov ebx, 1
   mov know, r10
   mov rcx, know        ; i want to print the r10 register to screen
   ;mov edx, 10
   int 0x80 

   mov rax, r10         ; here i want to compare 
   cmp rax, ffff        ; if r10 has reached ffff in its inc
   je END               ; jump out of loop if ffff is reached
   jmp REDO  

END:

What am I doing wrong here; do I have to put r10 into a variable then put that in to rcx to print it to screen; does je mean if rax equals ffff jump; do I have to put a x after ffffx

Sep Roland
  • 33,889
  • 7
  • 43
  • 76
  • This won't even assemble (`mov know, r10` and undefined symbol/label `ffff`), but you didn't include the error messages from your [mcve]. – Peter Cordes Jul 29 '22 at 23:10

1 Answers1

1

do I have to put a x after ffffx

If your 'ffff' is to be the hexadecimal representation of the number 65535, then write it as 0xFFFF, prepending the 0x hexadecimal prefix.

does je mean if rax equals ffff jump

The je mnemonic stands for JumpIfEqual. Your code will jump if rax equals 0xFFFF.

I think my loop is wrong ...

Good news: your loop is correct, but you could write it somewhat better:

  • For testing the loop termination condition where r10 equals 0xFFFF, you don't need to first copy r10 to rax.
  • And instead of exiting the loop on r10 == 0xFFFF, better continue the loop on r10 != 0xFFFF. It will save you from writing the extra unconditional jmp.

... and the r10 register is not printing to the screen

For NASM, an instruction like mov know, r10 makes no sense. In this instruction, know is merily an immediate number and it can't possibly be the destination of anything. You were trying to store the contents of the r10 register in the buffer pointed at by know. The correct instruction would be mov [know], r10 using the square brackets.
An instruction like mov rcx, know is fine since it moves an immediate number (the address of know) into the register. Immediates can be the source operand.


Displaying a number requires you to convert the binary value into a string of characters that represent decimal digits.
The following Q/A's explain the process:

The value in r10 seems small enough, that we should not use the 64-bit division and instead use the faster 32-bit division:

know    resb 64
        ...

REDO:   inc  r10d

        mov  eax, r10d
        mov  ebx, know + 63  ; High up in the buffer
        mov  ecx, ebx
        mov  edi, 10         ; CONST
.more:  xor  edx, edx
        div  edi
        add  edx, '0'        ; Remainder [0,9] -> ["0","9"]
        mov  [rcx], dl
        dec  ecx
        test eax, eax
        jnz  .more
        mov  byte [rcx], ' ' ; Leading space

        sub  ebx, ecx        ; Number of digits
        lea  edx, [rbx + 1]  ; plus the leading space char
        mov  ebx, 1
        mov  eax, 4
        int  0x80

        cmp  r10d, 0x0000FFFF
        jne  REDO
END:

The leading space was added so that the numbers are not sticking together in this long series of numbers.


My previous answer nasm linux x64 how do i find and cmp EOF to stop printing data from file to screen already warned you about using int 0x80 in 64-bit code. Today you still use it; was anything not clear from the link that I gave you?

know    resb 64
        ...

REDO:   inc  r12d

        mov  eax, r12d
        mov  rbx, know + 63  ; High up in the buffer
        mov  rsi, rbx
        mov  edi, 10         ; CONST
.more:  xor  edx, edx
        div  edi
        add  edx, '0'        ; Remainder [0,9] -> ["0","9"]
        mov  [rsi], dl
        dec  rsi
        test eax, eax
        jnz  .more
        mov  byte [rsi], ' ' ; Leading space

        sub  rbx, rsi        ; Number of digits
        lea  edx, [rbx + 1]  ; plus the leading space char
        mov  edi, 1
        mov  eax, 1
        syscall

        cmp  r12d, 0x0000FFFF
        jne  REDO
END:
Sep Roland
  • 33,889
  • 7
  • 43
  • 76
  • It's not a good idea to use the `int 0x80` 32-bit ABI in 64-bit code. This code will break if linked into a PIE executable (so the address of `know` will be outside the low 32 bits, so `int 0x80` only looking at ECX as the address won't get a valid pointer). [What happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code?](https://stackoverflow.com/q/46087730) – Peter Cordes Jul 29 '22 at 22:12