我用x64汇编编写了一个程序,将字符串的小写字母替换为星号。汇编过程从c++程序中调用,并接收一个字符数组。类似的逻辑适用于x86(不同之处在于使用的寄存器等),但现在为x64构建时,字符串保持不变。我使用Debian Linux和nasm
。
section .text
global func
func:
push rbp
mov rbp, rsp
; zadanie jako takie
mov rax, QWORD [rbp+8]
loop:
cmp BYTE [rax], 97
jl increment
cmp BYTE [rax], 122
jg increment
mov BYTE [rax], 42
increment:
add rax, 1
cmp BYTE [rax], 0
jne loop
exit:
mov rax, 0 ;return 0
mov rsp, rbp
pop rbp
ret
从下面的c++程序调用:
#include <stdio.h>
#define LENGTH 1024
extern "C" int func(char *a);
int main(void)
{
int result;
char text[LENGTH];
printf( "Write some stringn" );
fgets( text, LENGTH -1, stdin );
printf("String: %sn", text);
result=func(text);
printf("String: %sn", text);
return 0;
}
如有必要,这里是makefile
:
CC=gcc
ASMBIN=nasm
all : asm cc link
asm :
$(ASMBIN) -o func.o -f elf64 -l func.lst func.asm
cc :
$(CC) -m64 -c -g -O0 main.cc
link :
$(CC) -m64 -o test -lstdc++ main.o func.o
clean :
rm *.o
rm test
rm errors.txt
rm func.lst
此外,如果能提供从x86移植到x64的资源,我们将不胜感激。
程序不能工作的原因是x64中不同的调用约定。参考:链接。字符串数组的地址不像x86那样通过堆栈传递,而是存储在rdi寄存器中。因此,解决方案是将加载数组地址的指令更改为:
mov rax, rdi