簡體   English   中英

ASM at&t語法

[英]ASM at&t syntax

所以我對這段代碼有疑問。 這是一個從二進制數轉換為近數的程序。

#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;
}

它給了我:“分段錯誤(核心轉儲)”

請幫助這個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
$ ./sample 

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM