1 //:: call
 2 
 3 :(scenario call_imm32)
 4 % Reg[ESP].u = 0x64;
 5 # op  ModR/M  SIB   displacement  immediate
 6   e8                              a0 00 00 00  # call function offset at 0x000000a0
 7   # next EIP is 6
 8 +run: call imm32 0x000000a0
 9 +run: decrementing ESP to 0x00000060
10 +run: pushing value 0x00000006
11 +run: jumping to 0x000000a6
12 
13 :(before "End Single-Byte Opcodes")
14 case 0xe8: {  // call imm32 relative to next EIP
15   int32_t offset = imm32();
16   trace(2, "run") << "call imm32 0x" << HEXWORD << offset << end();
17   push(EIP);
18   EIP += offset;
19   trace(2, "run") << "jumping to 0x" << HEXWORD << EIP << end();
20   break;
21 }
22 
23 //:
24 
25 :(scenario call_r32)
26 % Reg[ESP].u = 0x64;
27 % Reg[EBX].u = 0x000000a0;
28 # op  ModR/M  SIB   displacement  immediate
29   ff  d3                                       # call function offset at EBX
30   # next EIP is 3
31 +run: call to r/m32
32 +run: r/m32 is EBX
33 +run: decrementing ESP to 0x00000060
34 +run: pushing value 0x00000003
35 +run: jumping to 0x000000a3
36 
37 :(before "End Op ff Subops")
38 case 2: {  // call function pointer at r/m32
39   trace(2, "run") << "call to r/m32" << end();
40   int32_t* offset = effective_address(modrm);
41   push(EIP);
42   EIP += *offset;
43   trace(2, "run") << "jumping to 0x" << HEXWORD << EIP << end();
44   break;
45 }
46 
47 :(scenario call_mem_at_r32)
48 % Reg[ESP].u = 0x64;
49 % Reg[EBX].u = 0x10;
50 % SET_WORD_IN_MEM(0x10, 0x000000a0);
51 # op  ModR/M  SIB   displacement  immediate
52   ff  13                                       # call function offset at *EBX
53   # next EIP is 3
54 +run: call to r/m32
55 +run: effective address is 0x10 (EBX)
56 +run: decrementing ESP to 0x00000060
57 +run: pushing value 0x00000003
58 +run: jumping to 0x000000a3
59 
60 //:: ret
61 
62 :(scenario ret)
63 % Reg[ESP].u = 0x60;
64 % SET_WORD_IN_MEM(0x60, 0x00000010);
65 # op  ModR/M  SIB   displacement  immediate
66   c3
67 +run: return
68 +run: popping value 0x00000010
69 +run: jumping to 0x00000010
70 
71 :(before "End Single-Byte Opcodes")
72 case 0xc3: {  // return from a call
73   trace(2, "run") << "return" << end();
74   EIP = pop();
75   trace(2, "run") << "jumping to 0x" << HEXWORD << EIP << end();
76   break;
77 }