0

the question is to write assembly program to calculate n!. n is in rdi, the result should be in rdx:rax. If the result can not be written in rdx:rax, the maximal number that fit in rdx:rax should be returned. In the link below is the correct answer. I only have a small question: why "ja 3f" and not simply "ja 3" in line 3, and why "ja 1b" in line 17 ? What is the meaning of "f" and "b" here?

factorial:
    cmp rdi, 34
    ja 3f
    xor edx, edx // Result stored in rdx:rax
    mov eax, 1
    cmp edi, 1
    jbe 2f    
1:  // Compute rdx:rax = rdx:rax * rdi
    // New rdx: rdx*rdi + (rax*rdi >> 64)
    // New rax: rax*rdi
    mov rcx, rdi
    imul rcx, rdx // First part of new rdx
    mul rdi // New rax + second part of new rdx
    sub edi, 1
    add rdx, rcx // New rdx
    cmp edi, 1

    ja 1b // Break loop if edi <= 1
2:  ret

3:  mov rax, -1
    mov rdx, -1
    ret
Michael Petch
  • 46,082
  • 8
  • 107
  • 198
shiro
  • 17
  • 3

1 Answers1

3

1:, 2:, and so on, are "local labels" in GNU assembler syntax, and f and b tell the assembler where to go look for these labels.

Within a source file there can be many labels whose name is the same single digit. 3f means the next label 3: after the current line, 3b means the nearest one before that.

Such labels are very useful because if you want to go just a handful of lines back or forward you don't have to think of a unique name each time, and the code is suitable to copy+paste into other files without thinking about what names may already be used. If you are going much further than that you should probably think of a meaningful name to make it easier to read.

See the GNU as manual for more details.

Sep Roland
  • 33,889
  • 7
  • 43
  • 76
Tom V
  • 4,827
  • 2
  • 5
  • 22