"案例表"如何在NASM中运行?

Rak*_*man 1 x86 assembly nasm

作为我们任务的一部分,我们应该用矩阵做各种函数.对于菜单,我们被分配使用"案例表"(它实现为2-D数组,每行只包含一个字母常量及其相应的函数)

我真的无法理解笔记,这本书是零帮助(它根本没有提到它们)

    .data
CaseTable BYTE 'A'  ; lookup value
    DWORD Process_A ; address of procedure
    EntrySize = ($ - CaseTable)
    BYTE 'B'
    DWORD Process_B
    BYTE 'C'
    DWORD Process_C
    BYTE 'D'
    DWORD Process_D

NumberOfEntries = ($ - CaseTable) / EntrySize
….
segment .text
...
    mov ebx, CaseTable  ; point EBX to the table
    mov ecx,NumberOfEntries ; loop counter

L1: cmp al,[ebx]    ; match found?
    jne L2  ; no: continue
    call PTR [ebx + 1]  ; yes: call the procedure
    jmp L3  ; and exit the loop
L2: add ebx,EntrySize   ; point to next entry
    loop L1 ; repeat until ECX = 0

L3:
Run Code Online (Sandbox Code Playgroud)

有人能帮助我理解这个吗?

Ale*_*nze 5

这个想法很微不足道.如果您不了解汇编语言,请尝试理解以下等效C代码(我冒昧地定义Process _*()作为打印不同的字母并抛出main()):

#include <stdio.h>

void Process_A(void)
{
  printf("A\n");
}

void Process_B(void)
{
  printf("B\n");
}

void Process_C(void)
{
  printf("C\n");
}

void Process_D(void)
{
  printf("D\n");
}

typedef struct
{
  char Char;
  void (*Subroutine)(void);
} CaseTableEntry;

CaseTableEntry CaseTable[] =
{
  { 'A', &Process_A }, // equivalent to "BYTE 'A'" + "DWORD Process_A"
  { 'B', &Process_B },
  { 'C', &Process_C },
  { 'D', &Process_D }
};

void Process(char Char)
{
  const size_t NumberOfEntries = sizeof(CaseTable) / sizeof(CaseTableEntry);
  CaseTableEntry* entry = &CaseTable[0]; // equiv to "mov ebx, CaseTable"
  size_t count = NumberOfEntries; // equiv to "mov ecx, NumberOfEntries"

  do
  {
    // "L1:" would be here
    if (entry->Char == Char) // equiv to "cmp al,[ebx]" + "jne L2"
    {
      entry->Subroutine(); // equiv to "call PTR [ebx + 1]"
      break; // equiv to "jmp L3"
    }
    // "L2:" would be here
    entry++; // equiv to "add ebx, EntrySize"
  } while (--count > 0); // equiv to "loop L1"
  // "L3:" would be here
}

int main(void)
{
  Process('A');
  Process('B');
  Process('X');
  Process('C');
  Process('D');
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

A
B
C
D
Run Code Online (Sandbox Code Playgroud)

这里唯一的问题可能是$mov ebx, CaseTable.

$计算包含表达式的行开头的程序集位置; 所以你可以使用JMP $编写无限循环.

因此,EntrySize = ($ - CaseTable)计算表的第一个条目的大小,同样NumberOfEntries = ($ - CaseTable) / EntrySize首先计算整个表大小,然后将其除以一个条目的大小,给出表条目的数量.

与其他汇编程序(例如MASM和TASM)不同,在NASM中mov ebx, CaseTable意味着将指定对象的地址加载到ebx中CaseTable.在其他汇编程序中,这可能意味着从名为对象的前4个字节读入ebx CaseTable.同样,DWORD Process_A定义一个包含所命名对象地址的DWORD Process_A.
在其他汇编程序中,等价物可能需要写为mov ebx, OFFSET CaseTableDWORD OFFSET Process_A.

其余的,请参阅您的书,NASM官方文档Intel/AMD的 x86 CPU手册.基本上做你的功课.如果有任何不清楚的地方,请来询问具体问题.