我正在x86汇编(使用NASM)中进行一项练习,该练习的利基要求是将每条指令限制为最多3个字节。
我想调用标签,但是执行此操作的正常方法(如代码示例所示)总是导致指令大小为5个字节。我试图找出是否有一系列指令(每个指令不超过3个字节)可以完成此操作。
我试图将标签地址加载到一个寄存器中,然后调用该寄存器,但是似乎该地址随后被解释为绝对地址,而不是相对地址。
我环顾四周,看看是否有一种方法可以强制调用以将寄存器中的地址解释为相对地址,但找不到任何内容。我曾考虑过通过将返回地址推入堆栈并使用来模拟呼叫jmp rel8,但不确定如何获取要返回的位置的绝对地址。
这是做我想要的正常方法:
[BITS 32]
call func ; this results in a 5-byte call rel32 instruction
; series of instructions here that I would like to return to
func:
; some operations here
ret
Run Code Online (Sandbox Code Playgroud)
我已经尝试过像这样的事情:
[BITS 32]
mov eax, func ; 5-byte mov r32, imm32
call eax ; 2-byte call r32
; this fails, seems to interpret func's relative address as an absolute
... ; series of instructions here …Run Code Online (Sandbox Code Playgroud) 考虑下面的例子中,我创建了局部变量specialNumber中main(),并通过引用传递到一个新的线程,以及其他功能(请无视缺乏锁定/互斥的):
#include <iostream>
#include <thread>
void threadRun(int& number) {
while(true) {
std::this_thread::sleep_for(std::chrono::seconds(2));
std::cout << number << std::endl;
number += 1;
}
}
int main() {
int specialNumber = 5;
std::thread newThread(threadRun, std::ref(specialNumber));
otherFunction(specialNumber);
newThread.join();
}
void otherFunction(int& number) {
// does something with number
}
Run Code Online (Sandbox Code Playgroud)
我知道通常应该避免传递对局部变量的引用,因为一旦该函数终止,变量将超出范围并且引用将无效。
但是,由于变量是 局部的main(),并且该函数在整个程序终止之前不会终止,这种做法有什么问题吗?
我的具体用例是在这里存储一个小对象(主要由指向堆对象的指针和辅助函数组成),它将被多个线程和/或函数使用,并传递对它的引用。我知道另一种方法是使用智能指针将其存储在堆中,例如shared_ptr,但以这种方式存储这么小的对象对我来说似乎效率低下。
如果我的任何术语不正确,我深表歉意,我对 C++ 很陌生。请纠正我!