Kor*_*rth 1 c++ x86 assembly xor bit
该问题与用伽马序列加密字符串的函数有关。
函数调用:
cout << "\ncipher with code: ";
for (register int i = 0; i < str.length(); i++) {
str[i] = fun_cipher_gamma(str[i], gamma[i]);
cout << str[i];
}
cout << endl;
Run Code Online (Sandbox Code Playgroud)
函数本身:
char fun_cipher_gamma(register char simbol, register char gamma)
{
char result = ' ';
funct();
return result;
}
Run Code Online (Sandbox Code Playgroud)
汇编代码:
.MODEL FLAT, C
.STACK 256
.DATA
.CODE
EXTRN gamma : BYTE
EXTRN simbol : BYTE
EXTRN result : BYTE
PUBLIC funct
funct PROC far
mov al, simbol
mov bl, gamma
xor al, bl
mov result, al
retn
funct ENDP
END
Run Code Online (Sandbox Code Playgroud)
使用调试器我意识到汇编语言函数不返回结果,但我不明白如何修复它。
我认为我需要使用push
,但我不确定并且我迷失了,因为我的汇编语言技能几乎不存在
这个函数在 C++ 中运行成功,我需要用汇编语言重做它的逻辑:
return btowc(simbol) ^ btowc(gamma);
Run Code Online (Sandbox Code Playgroud)
UPD:在 .cpp 中,我添加了这些外部函数:
extern "C" char funct(void);
extern "C" unsigned char gamma = ' ';
extern "C" unsigned char simbol = ' ';
extern "C" unsigned char result = ' ';
Run Code Online (Sandbox Code Playgroud)
小智 6
正如 @Chris Dodd 提到的,您没有在程序集中使用全局变量!
最好使用调用约定,而不是使用全局变量作为参数。它提高了可读性并使其更易于理解。
extern "C" char funct(unsigned char symbol, unsigned char gamma);
char fun_cipher_gamma(unsigned char symbol, unsigned char gamma)
{
return funct(symbol, gamma);
}
Run Code Online (Sandbox Code Playgroud)
; in C calling convention:
; Caller passes Parameters via stack and all arguments are pushed to stack as dwords (4 byte)
; Callee should preserve EBX, ESI, EDI, EBP, and ESP
; and use EAX to return a value
push ebp ; Callee should preserver old value of EBP
mov ebp, esp ; set the base pointer to stack pointer
; sub esp, 8 ; make room for 8 byte of variables (commented out because we aren't using it)
; push any other registers that you'll use HERE
; ...
; [ebp - 12] = local variable #3
; [ebp - 8] = local variable #2
; [ebp - 4] = local variable #1
; [ebp + 0] = old EBP the we pushed
; [ebp + 4] = return address
; [ebp + 8] = parameter #1
; [ebp + 12] = parameter #2
; [ebp + 16] = parameter #3
; [ebp + 20] = parameter #4
; ...
; so this means "symbol" is at [ebp + 8] and gamma is at [ebp + 12]
; [ebp + 8] = symbol
; [ebp + 12] = gamma
mov eax, [ebp + 8]
xor eax, [ebp + 12]
; pop saved registers HERE
mov esp, ebp ; restore ESP to its original value
pop ebp ; restore EBP's value
ret
Run Code Online (Sandbox Code Playgroud)
但请注意,现在使用汇编不会提高程序的性能(事实上,您可能会损失性能),编译器编写的汇编比我们更快。
如果它们没有优化,则可能会编写比编译器更快的程序集,但一旦您启用优化,它们就会编写比您更快的程序集。
MSVC19 编译了这个:
; in C calling convention:
; Caller passes Parameters via stack and all arguments are pushed to stack as dwords (4 byte)
; Callee should preserve EBX, ESI, EDI, EBP, and ESP
; and use EAX to return a value
push ebp ; Callee should preserver old value of EBP
mov ebp, esp ; set the base pointer to stack pointer
; sub esp, 8 ; make room for 8 byte of variables (commented out because we aren't using it)
; push any other registers that you'll use HERE
; ...
; [ebp - 12] = local variable #3
; [ebp - 8] = local variable #2
; [ebp - 4] = local variable #1
; [ebp + 0] = old EBP the we pushed
; [ebp + 4] = return address
; [ebp + 8] = parameter #1
; [ebp + 12] = parameter #2
; [ebp + 16] = parameter #3
; [ebp + 20] = parameter #4
; ...
; so this means "symbol" is at [ebp + 8] and gamma is at [ebp + 12]
; [ebp + 8] = symbol
; [ebp + 12] = gamma
mov eax, [ebp + 8]
xor eax, [ebp + 12]
; pop saved registers HERE
mov esp, ebp ; restore ESP to its original value
pop ebp ; restore EBP's value
ret
Run Code Online (Sandbox Code Playgroud)
对此:
xor cl, dl
mov al, cl
ret 0
Run Code Online (Sandbox Code Playgroud)
它使用更少的空间,同时比我们的实现更快(它使用fastcall
调用约定)。
有关调用约定的更多信息:https ://www.dyncall.org/docs/manual/manualse11.html