【发布时间】:2021-06-27 05:16:07
【问题描述】:
我编写了以下要在 C 程序中调用的 x86-64 函数: 第一个接收一个 2 位十六进制字符并将其位向右旋转一位,即,如果 '12'(表示 0x12 但不作为输入提供 0x)向右旋转一位以给出 '09' (0x09)
.file "rotate_right.s"
.section .rodata
.data
.globl rotate_right
.type rotate_right, @function
.text
rotate_right:
pushq %rbp
movq %rsp,%rbp
pushq %rsi
pushq %rdi
pushq %rbx
subl $4, %esp
movb 8(%ebp), %al
sarb $1, %al
leave
ret
.size rotate_right, .-rotate_right
同样,该函数将位向左旋转一位,因此 '12'(0x12) 变为 '24'(0x24)。
.file "rotate_left.s"
.section .rodata
.data
.globl rotate_left
.type rotate_left, @function
.text
rotate_left:
pushq %rbp
movq %rsp,%rbp
pushq %rsi
pushq %rdi
pushq %rbx
subl $4, %esp
movb 8(%ebp), %al
sarb $1, %al
leave
ret
.size rotate_left, .-rotate_left
create_key() 函数获取 0110 等 4 位输入,并将 8 位输出作为无符号整数输出,即 01100110:
.file "create_key.s"
.section .rodata
ask_key:
.string "Enter 4-bit key:"
.data
.globl create_key
.type create_key, @function
.text
create_key:
pushq %rbp
# stack holding
movq %rsp, %rbp
movl $ask_key, %edi
# printing the ask string
movl $0, %eax
# calling the C functions
call printf
movl $0,%esi
# rsi is set to 0. the key
pushq %rsi
# take it to the stack
# call getchar for getting each key bit
call getchar
popq %rsi
subl $48,%eax
# doing this will give us 1 or 0 if the we input 1 or 0
sall $1,%esi
# shift the key by one bit
orl %eax,%esi
# OR key and the sigle input
pushq %rsi
# push rsi to stack to save the value in rsi
# Do the above operation a total of 4 times
call getchar
popq %rsi
subl $48,%eax
sall $1,%esi
orl %eax,%esi
pushq %rsi
call getchar
popq %rsi
subl $48,%eax
sall $1,%esi
orl %eax,%esi
pushq %rsi
call getchar
popq %rsi
subl $48,%eax
sall $1,%esi
orl %eax,%esi
# copy first 4-bits of the key into %rax
movl %esi,%eax
#left shift the key 4 times
sall $4,%esi
# OR the secont 4-bits into %rax
orl %esi,%eax
leave
ret
# return the values and end the function
.size create_key, .-create_key
这是 C 程序,
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
extern unsigned int create_key();
extern unsigned char rotate_left(unsigned char x);
extern unsigned char rotate_right(unsigned char x);
int main(){
/* This Part Takes The Input To Be Ciphered
And Prints The Hexadecimal Value*/
char word[200], outword[400], xor_hex[400], hex_rot[400], ch, hex[2];
unsigned int i_key, encodant, rotated;
int i, len, j;
/* i_key is the integer equvivalent of the cipher key*/
printf("enter cleartext:");
i = 0;
ch = getchar();
while(ch!='\n'){
word[i] = ch;
++i;
ch = getchar();
}
fflush(stdin);
len = i;
word[i] = '\0';
printf("%s\n", word);
printf("hex encoding:\n");
for(i = 0; i<len; i++){
sprintf(outword+(i*2), "%02X", word[i]);
}
for(i=0;i<(2*len);i++){
if(i%2==0 & i>0)printf(" ");
if(i%20==0 & i>0)printf("\n");
printf("%c", outword[i]);
}
printf("\n");
/* This Part Asks For The Cipher Key */
i_key = create_key();
/* XOR Encoding of the Hex Cyphertext*/
for(i=0;i<len*2;i+=2){
hex[0] = outword[i];
hex[1] = outword[i+1];
encodant = (int)strtol(hex, NULL, 16);
sprintf(xor_hex+(i), "%02X", (i_key^encodant));
}
/* Encoding the text using bit rotation */
j=1;
for(i=0;i<len*2;i+=2){
hex[0]=xor_hex[i];
hex[1]=xor_hex[i+1];
encodant = (int)strtol(hex, NULL, 16);
if(j%2==0)rotated = rotate_right(encodant);
else rotated = rotate_left(encodant);
j++;
sprintf(hex_rot+(i), "%02X", rotated);
}
/* Printing The Finished Ciphered Text */
printf("hex ciphertext:\n");
for(i=0;i<(2*len);i++){
if(i%2==0 & i>0)printf(" ");
if(i%20==0 & i>0)printf("\n");
printf("%c", hex_rot[i]);
}
printf("\n");
return 0;
}
函数原型不能改变,即rotate函数必须是char并且有char参数,create_key函数表面上很好,但是我的代码给出了分段错误。我不知道在这种情况下该怎么做,因此感谢您的帮助。
【问题讨论】:
-
我不太习惯汇编语言,但这看起来很奇怪:
pushq %rbp movq %rsp,%rbp。如果我是正确的,这会将 RBP 保存到堆栈中,但使用 RBP 擦除堆栈指针。不应该是movq %rbp, %rsp吗? -
超级常见的FAQ:使用
int作为getchar的结果。fflush(stdin)是未定义的行为。您似乎需要其他学习 C 的资源,因为您当前的资源教错了。 -
您是否在调试器中运行您的程序?它会将您指向错误访问的位置。 -- 你有单独检查你的汇编函数吗?
-
我对几天前自己开始的 x86-64 Att 组装了解不多。
-
每当我尝试单独编译它们时,我都会收到两个旋转函数的错误消息: