简体   繁体   English

宏汇编中与位置无关的代码

[英]Position independent code in macro-assembly

Write a NASM macro: divide, which has 2 arguments, which specify unsigned integers in any addressing mode. 编写一个NASM宏:除法,它具有2个参数,这些参数在任何寻址模式下均指定无符号整数。 The macro computes the ceiling of its first argument, divided by its second argument, and places the result in register edx. 宏计算其第一个参数的上限,除以第二个参数,并将结果放入寄存器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. 如果第二个参数为0(要在运行时进行测试),则结果应为0,并且应将一条消息“除以零”打印到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). 尽管如此,以上代码中的所有跳转和调用指令都是eip相对的(请参阅文档中jmp / jcc和调用指令的详细信息)。

For that reason jne rest1 and jmp end1 don't make the macro position-dependent. 因此, jne rest1jmp end1不会使宏依赖于位置。 These jumps always advance eip by a constant amount, irrespective of where the code is located. 无论代码位于何处,这些跳转总是使eip前进一定的量。

OTOH, for that same reason call printf (and possibly push LC1 ) do(es) make the macro position-dependent. OTOH,出于同样的原因, call printf (可能还可以push LC1 )使宏位置相关。 You can avoid this by passing the addresses of printf and LC1 into the macro as additional arguments (either explicit (as with other two arguments) or implicit (eg in some predefined place, register or stack location)). 您可以通过将printfLC1的地址作为附加参数(显式(与其他两个参数一样)或隐式(例如,在某些预定义的位置,寄存器或堆栈位置))传递给宏来避免这种情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM