Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 美国电话电报公司;t语法_C++_Unix_Assembly - Fatal编程技术网

C++ 美国电话电报公司;t语法

C++ 美国电话电报公司;t语法,c++,unix,assembly,C++,Unix,Assembly,所以我对这个代码有一个问题。这是一个将二进制数转换为十进制数的程序 #include <cstdlib> #include <iostream> #include <cstdio> char s[100]; int length; int a; int main(int argc, char *argv[]) { system("cls"); printf("\n\n Vvedite stroky iz 0 i 1 (

所以我对这个代码有一个问题。这是一个将二进制数转换为十进制数的程序

#include <cstdlib>
#include <iostream>
#include <cstdio>

char s[100];
    int length;
    int a;


int main(int argc, char *argv[])
{

    system("cls");
    printf("\n\n  Vvedite stroky iz 0 i 1 (do 8 delementov) > ");
    gets(s);

    asm("leal s,%esi");
    asm("movl 8,%ecx");
    asm("movl 0,%edx");
    asm("repeat:");
    asm("movl 1,%eax");
    asm("dec %ecx");
    asm("rol %cl,%eax");
    asm("cmpb 31,%esi");
    asm("jnz x");
    asm("add %eax,%edx");
    asm("x: inc %esi");
    asm("cmpb 0,$esi");
    asm("jnz repeat");
    asm("movl %edx,a");

    printf("4islo %d",a);

    return EXIT_SUCCESS;
}
#包括
#包括
#包括
chars[100];
整数长度;
INTA;
int main(int argc,char*argv[])
{
系统(“cls”);
printf(“\n\n Vvedite stroky iz 0 i 1(do 8 delementov)>”;
获取(s);
asm(“leal s,%esi”);
asm(“movl 8,%ecx”);
资产负债表(“0月移动百分比,edx”);
asm(“重复:”);
asm(“movl 1,%eax”);
asm(“十二月%ecx”);
asm(“rol%cl,%eax”);
asm(“cmpb 31%,esi”);
asm(“jnz x”);
asm(“添加%eax,%edx”);
asm(“x:inc%esi”);
asm(“cmpb 0,$esi”);
asm(“jnz重复”);
asm(“移动百分比edx,a”);
printf(“4islo%d”,a);
返回退出成功;
}
它给了我: “分段故障(堆芯转储)”

请帮助完成此ASM部分。
我认为CMPB运算符中存在问题。

该代码存在一些问题-在我的系统中,它甚至没有通过编译器/汇编程序运行。主要问题是,您需要在所有文本前面加上
$
,否则汇编程序将假定内存访问:

asm("movl 8,%ecx"); // tries to access memory at address 8 => Segmentation fault
这需要改进

asm("movl $8,%ecx"); // Moves literal 8 into ecx
相应地调整所有其他说明

另一个问题是以下说明:

asm("cmpb 0,$esi");   // $esi is not a literal nor a register name
这需要改进

asm("cmpb $0,(%esi)");  // compare value at address stored in %esi with literal 0 (end of string)
我建议您使用调试信息编译代码,如

$ g++ -g -o sample sample.c
这样就很容易调试程序:

$ gdb sample 
(gdb) run
Starting program: sample 
sh: cls: command not found

   Vvedite stroky iz 0 i 1 (do 8 delementov) > 10101010

Program received signal SIGSEGV, Segmentation fault.
main (argc=1, argv=0x7fffffffe238) at sample.c:18
18          asm("movl 8,%ecx");   // current bit position
如您所见,调试器向您显示导致分段错误的指令

更新

使用@Brett建议的单个
asm
语句为我工作的汇编代码:

asm("leal s, %esi         \n\t"   // s => %esi
    "movl $8, %ecx        \n\t"   // current bit position (+1)
    "movl $0, %edx        \n"     // initialize result

"repeat:                  \n\t"
    "movl $1, %eax        \n\t"   // Create bit mask in %eax
    "dec  %ecx            \n\t"   // Decrement rotation counter to shift mask bit to proper position
    "rol  %cl, %eax       \n\t"   // calculate value of current binary digit

    "cmpb $0x31, (%esi)   \n\t"   // current digit == 1?
    "jnz  x               \n\t"   // no, skip
    "add  %eax, %edx      \n"     // add current value to %edx

 "x:                      \n\t"
    "inc  %esi            \n\t"   // next address in input string
    "cmpb $0, (%esi)      \n\t"   // end of string reached?
    "jnz  repeat          \n\t"   // no, continue

    "movl %edx,a          \n");   // store result in a variable

我个人避免使用AT&T语法,但您不应该在所有立即数前面加上
$
,在所有寄存器前面加上
%
?(例如,
cmpb 0,$esi
行应该是
cmpb$0,%esi
)。在我看来,这段代码根本不太接近于完成这项工作。在您完全习惯于编写汇编语言之前,通常最简单的方法是用c语言编写一些工作代码,然后用汇编语言编写(大致)相同的代码。每个
asm
语句都是独立的。您不能假定寄存器包含您在每个
asm
块之前或之后假定的值。您可能希望读取GCC内联程序集。@Andreas-没有输出、输入或被截断的操作数。从编译器的角度来看,它们没有效果。这里的漏洞是:
“没有任何输出操作数的asm指令被视为与易失性asm指令相同。”
,这只能保证
asm
语句不会被优化。编译器可以自由地在它们之间插入指令——实际上是否发生这种情况没有指定,因此不能依赖。(续)@Andreas。。。同样:
“…您不能期望一系列易失性asm指令保持完全连续。如果您希望连续输出,请使用单个asm。此外,GCC在易失性asm指令上执行一些优化…”
我更改了此代码并进行了编译,但它给出的asm为零(“leal s,%esi”);asm(“movl$8,%ecx”);asm(“movl$0,%edx”);asm(“重复:”);asm(“movl$1,%eax”);asm(“十二月%ecx”);asm(“rol%cl,%eax”);asm(“cmpl$31,%esi”);asm(“jnz x”);asm(“添加%eax,%edx”);asm(“x:”);asm(“包括%esi”);asm(“cmpl$0,%esi”);asm(“jnz重复”);asm(“移动百分比edx,a”);printf(“4islo%d\n”,a)
cmpl$31,%esi
需要是
cmpb$31,(%esi)
(间接寻址),对于
cmpl$0,%esi
,这需要是
cmpb$0,(%esi)
注意
$31
也需要是
$0x31
(十六进制值
0x31
是ASCII“1”,而不是十进制值
31
$ ./sample 

  Vvedite stroky iz 0 i 1 (do 8 delementov) > 10101010
4islo 170