作为我们任务的一部分,我们应该用矩阵做各种函数。对于菜单,我们被指定使用“案例表”(实现为二维数组,每行只包含一个字母常量及其相应的函数)
我真的无法理解这些笔记,这本书是零帮助(它根本没有提到它们)
.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:
有人可以帮助我理解这个吗?
答案 0 :(得分: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;
}
输出:
A
B
C
D
此处唯一的问题可能是$
和mov ebx, CaseTable
。
因此EntrySize = ($ - CaseTable)
计算表的第一个条目的大小,同样NumberOfEntries = ($ - CaseTable) / EntrySize
首先计算整个表大小,然后将其除以一个条目的大小,给出表条目的数量
与其他汇编程序(例如MASM和TASM)不同,在NASM中mov ebx, CaseTable
表示将名为CaseTable
的对象的地址加载到ebx中。在其他汇编程序中,这可能意味着从名为CaseTable
的对象读入ebx的前4个字节。
同样,DWORD Process_A
定义了一个DWORD,其中包含名为Process_A
的对象的地址
在其他汇编程序中,等价物可能需要写为mov ebx, OFFSET CaseTable
和DWORD OFFSET Process_A
。
其他方面,请参阅您的书籍the official NASM documentation和Intel's / AMD's x86 CPU手册。基本上做你的功课。如果有任何不清楚的地方,请来询问具体的问题。