Write a NASM macro: divide, which has 2 arguments, which specify unsigned integers in any addressing mode. The macro computes the ceiling of its first argument, divided by its second argument, and places the result in register edx. If the second argument is 0 (to be tested at runtime), the result should be 0, and a message “divide by zero” should be printed to stdout.
This is the code I wrote. How to write this code without labels? (position independs code)
%macro divide 2
section .rodata
LC1: DB "divide by zero ", 10, 0
section .text
mov eax, %1
mov ebx, %2
cmp ebx, 0 ; divide by zero
jne rest1
push LC1
call printf
add esp,4
mov edx, 0
jmp end1
rest1:
mov edx, 0
div ebx
add eax, edx
mov edx , eax ; the result should be in edx
end1:
%endmacro
There’s quite a difference between “no labels” and “position-independent code”. You can have one, but not the other, you can have both, you can have neither.
It’s not very easy to make the above code without labels. And I see no good reason why you would want that. Can you explain what you’re doing, the bigger goals behind this task?
It’s also unusual to make position-independent macros. Normally, things like an entire subroutine are made position-independent. Again, why do you think you need it?
Nonetheless, all jump and call instructions in the above code are
eip-relative (see the details of the jmp/jcc and call instructions in the documentation).For that reason
jne rest1andjmp end1don’t make the macro position-dependent. These jumps always advanceeipby a constant amount, irrespective of where the code is located.OTOH, for that same reason
call printf(and possiblypush LC1) do(es) make the macro position-dependent. You can avoid this by passing the addresses ofprintfandLC1into the macro as additional arguments (either explicit (as with other two arguments) or implicit (e.g. in some predefined place, register or stack location)).