GAS to NASM assembly: translate ".rept .set" to NASM (loop and assign incrementing value to label)

Viewed 261

GAS assembly knows about the .set-directive which can be combined with .rept to increment a label (variable) in a loop as in the example below:

pd:
  .set SPAGE, 0
  .rept 512
    .quad SPAGE + 0x87      // PRESENT, R/W, USER, 2MB
  .set SPAGE, SPAGE + 0x200000
  .endr

How can I achieve something similar convenient in NASM? I know about TIMES directive, but this alone doesn't help me to achieve, what I want. Any ideas? The EQU-directive from NASM only allows assigning a value once. Hence, it will not solve my problem.

1 Answers

Indeed this is impossible to do with times directive due to the operand to TIMES is a critical expression, to repeat more than one line of code, or a complex macro, use the preprocessor %rep directive, take a look at this silly example:

global    _start

section   .text
_start:
mov       rbx, 0
%assign i 0
%rep    5
        mov rbx, [variable]
        add rbx, i
        mov [variable], rbx
%assign i i+1
%endrep

mov       rax, 60                 ; system call for exit
mov       rdi, [variable]; value of 'variable' = 10
syscall

section .bss
variable: resb 1

Check the answer:

nasm -felf64 ass.asm && ld ass.o && ./a.out
echo $?
Related