0

编写一个 NASM 宏:divide,它有 2 个参数,指定任何寻址模式下的无符号整数。宏计算其第一个参数的上限,除以第二个参数,并将结果放入寄存器 edx。如果第二个参数为 0(要在运行时测试),则结果应为 0,并且应将消息“除以零”打印到标准输出。

这是我写的代码。如何编写没有标签的代码?(位置独立于代码)

%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
4

1 回答 1

0

“无标签”和“位置无关代码”之间存在很大差异。你可以拥有一个,但不能拥有另一个,你可以拥有两个,你也可以两个都拥有。

让上面的代码没有标签并不是很容易。我看不出你为什么想要这样的充分理由。你能解释一下你在做什么,这个任务背后的更大目标吗?

制作与位置无关的宏也很不寻常。通常,像整个子程序这样的东西是与位置无关的。再说一次,你为什么认为你需要它?

尽管如此,上述代码中的所有跳转和调用指令都是eip相对的(请参阅文档中的 jmp/jcc 和调用指令的详细信息)。

出于这个原因jne rest1jmp end1不要让宏观位置依赖。eip无论代码位于何处,这些跳转总是以恒定的量前进。

OTOH,出于同样的原因call printf(并且可能push LC1)确实使宏位置相关。printf您可以通过将和的地址作为附加参数传递到宏中来避免这种情况LC1(显式(与其他两个参数一样)或隐式(例如,在某个预定义的位置、寄存器或堆栈位置))。

于 2012-06-25T11:08:04.500 回答