【问题标题】:Translate a FOR to assembler将 FOR 转换为汇编器
【发布时间】:2009-11-07 22:14:56
【问题描述】:

我需要将方法中的注释翻译成汇编程序。我有一个大概的想法,但不能。

有人可以帮帮我吗?适用于 Intel x32 架构:

int 
secuencia ( int n, EXPRESION * * o )
{
  int a, i;
//--- Translate from here ...
  for ( i = 0; i < n; i++ ){
    a = evaluarExpresion( *o );
    o++;
  }
  return a ;
//--- ... until here.
}

翻译后的代码必须在 __asm 中:

__asm {
        translated code
}

谢谢,

最终更新:

这是最终版本,正在运行并已发表评论,感谢大家的帮助:)

int
secuencia ( int n, EXPRESION * * o )
{
    int a = 0, i;
    __asm
    {
        mov dword ptr [i],0             ; int i = 0
        jmp salto1
        ciclo1:
        mov eax,dword ptr [i]           
        add eax,1                       ; increment in 1 the value of i
        mov dword ptr [i],eax           ; i++
        salto1: 
        mov eax,dword ptr [i]           
        cmp eax,dword ptr [n]           ; Compare i and n
        jge final                       ; If is greater goes to 'final'
        mov eax,dword ptr [o] 
        mov ecx,dword ptr [eax]         ; Recover * o (its value)
        push ecx                        ; Make push of * o (At the stack, its value)
        call evaluarExpresion           ; call evaluarExpresion( * o )
        add esp,4                       ; Recover memory from the stack (4KB corresponding to the * o pointer)
        mov dword ptr [a],eax           ; Save the result of evaluarExpresion as the value of a
        mov eax,dword ptr [o]           ; extract the pointer to o
        add eax,4                       ; increment the pointer by a factor of 4 (next of the actual pointed by *o)
        mov dword ptr [o],eax           ; o++
        jmp ciclo1                      ; repeat
        final:                          ; for's final
        mov eax,dword ptr [a]           ; return a - it save the return value at the eax registry (by convention this is where the result must be stored)
    }
}

【问题讨论】:

  • 这是作业吗?如果是的话,不要指望有人会给你答案。展示你目前拥有的东西。
  • 为什么需要这样做?编译器完全有能力为您做到这一点。编译器输出不够好是不是有什么原因?
  • gcc为你做作业比找一个编程问答网站要快。试试man gcc
  • Professional Assembly 的自我作业......但我被卡住了!
  • 为了那些不会说西班牙语的人的利益,您会考虑将 cmets 翻译成英文吗?我会自己做,除非这似乎不是我编辑帖子的正当理由,礼仪方面

标签: c assembly x86


【解决方案1】:

基本上在汇编语言中,严格来说没有循环的概念,就像在高级语言中一样。这一切都是通过跳转实现的(例如,作为“goto”...)

也就是说,x86 有一些指令假设您将编写“循环”,隐式使用寄存器 ECX 作为循环计数器。

一些例子:

    mov ecx, 5         ; ecx = 5
.label:
    ; Loop body code goes here
    ; ECX will start out as 5, then 4, then 3, then 1...
    loop .label        ; if (--ecx) goto .label;

或者:

    jecxz .loop_end    ; if (!ecx) goto .loop_end;
.loop_start:
    ; Loop body goes here
    loop .loop_start   ; if (--ecx) goto .loop_start;
.loop_end:

而且,如果你不喜欢这个 loop 指令倒数...你可以写这样的东西:

    xor ecx, ecx       ; ecx = 0
.loop_start:
    cmp ecx, 5         ; do (ecx-5) discarding result, then set FLAGS
    jz .loop_end       ; if (ecx-5) was zero (eg. ecx == 5), jump to .loop_end
    ; Loop body goes here.
    inc ecx            ; ecx++
    jmp .loop_start
.loop_end:

这将更接近典型的for (int i=0; i&lt;5; ++i) { }

【讨论】:

  • 我同意... asveikau:这是一个非常好的解释,现在我从哪里开始。非常感谢。
【解决方案2】:

注意

for (init; cond; advance) {
    ...
}

本质上是

的语法糖
init;
while(cond) {
   ...
   advance;
}

如果你在课堂上专心听讲,这应该很容易翻译成汇编语言。

【讨论】:

  • 谢谢,所以我可以使用注册表...递减和跳跃...嗯,现在我有一个形状
【解决方案3】:

使用gcc生成汇编代码

gcc -S -c sample.c

man gcc 是你的朋友

【讨论】:

  • 或者:伙计,gcc 是你的朋友! LOL,一个生成汇编语言的编译器。谁会想到呢。
  • 哈哈,gcc 的手册页可能有用,但请注意 gcc 的手册页有 12,838 行! “-S”选项直到第 678 行才出现!
  • @rascher 必须阅读?打消念头!正则表达式兼容搜索?异端! ;)
【解决方案4】:

为此,您可能会使用循环指令,该指令在每个循环中递减 ecx(通常称为扩展计数器)并在 ecx 达到零时熄灭。但是为什么要使用内联 asm 呢?我很确定编译器会正确优化这么简单的东西......

(我们说 x86 架构,因为它基于 80x86 计算机,但这是一个“ok”的错误 =p)

【讨论】:

  • Jejej 谢谢...我已经做了几年软件开发...但现在是我开始自学有关 PC 架构、汇编程序等的时候了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-06-13
  • 1970-01-01
  • 1970-01-01
  • 2021-04-23
  • 2013-01-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多