2010-03-07 21 views
5

tôi viết một chức năng asm trong Delphi 7 nhưng nó biến đổi mã của tôi để cái gì khác:Nhãn Delphi và sự kỳ quặc?

function f(x: Cardinal): Cardinal; register; 
label err; 
asm 
    not eax 
    mov edx,eax 
    shr edx, 1 
    and eax, edx 
    bsf ecx, eax 
    jz err 
    mov eax, 1 
    shl eax, cl 
    mov edx, eax 
    add edx, edx 
    or eax, edx 
    ret 
    err: 
    xor eax, eax 
end; 

// compiled version 
f: 
    push ebx  // !!! 
    not eax 
    mov edx,eax 
    shr edx, 1 
    and eax, edx 
    bsf ecx, eax 
    jz +$0e 
    mov eax, 1 
    shl eax, cl 
    mov edx, eax 
    add edx, edx 
    or eax, edx 
    ret 
    err: 
    xor eax, eax 
    mov eax, ebx // !!! 
    pop ebx  // !!! 
    ret 

// the almost equivalent without asm 
function f(x: Cardinal): Cardinal; 
var 
    c: Cardinal; 
begin 
    x := not x; 
    x := x and x shr 1; 
    if x <> 0 then 
    begin 
    c := bsf(x); // bitscanforward 
    x := 1 shl c; 
    Result := x or (x shl 1) 
    end 
    else 
    Result := 0; 
end; 

Tại sao nó tạo push ebxpop ebx? Và tại sao nó làm mov eax, ebx?

Dường như nó tạo khung ngăn xếp một phần vì mov eax, ebx.

kiểm tra đơn giản này tạo mov eax, edx nhưng không tạo ra rằng khung stack:

function asmtest(x: Cardinal): Cardinal; register; 
label err; 
asm 
    not eax 
    and eax, 1 
    jz err 
    ret 
    err: 
    xor eax, eax 
end; 

// compiled 
asmtest: 
    not eax 
    and eax, $01 
    jz +$01 
    ret 
    xor eax, eax 
    mov eax, edx // !!! 
    ret 

Dường như nó có cái gì để làm với label err. Nếu tôi loại bỏ điều đó, tôi không nhận được phần mov eax, *.

Tại sao điều này lại xảy ra?


Đã tạo báo cáo lỗi trên Quality Central.

+0

xin vui lòng báo cáo này như là một lỗi tại http://qc.embarcadero.com/wc/qcmain.aspx –

+0

@Jeroen chắc chắn. không có prob ... – Egon

+0

Bạn đã hỏi một số câu hỏi "tại sao" ở đây, nhưng không có câu hỏi nào được trả lời bằng câu trả lời bạn đã chấp nhận. Dường như bạn thực sự chỉ muốn biết làm thế nào để nhảy đến một hướng dẫn mới trong trình biên dịch Delphi mà không quan tâm đến lý do tại sao nỗ lực của riêng bạn thất bại. Điều đó có chính xác không? –

Trả lời

7

Các lời khuyên thực tế là: không sử dụng từ khóa nhãn trong mã asm, sử dụng @@ - nhãn tiền tố:

function f(x: Cardinal): Cardinal; register; 
asm 
    not eax 
    mov edx,eax 
    shr edx, 1 
    and eax, edx 
    bsf ecx, eax 
    jz @@err 
    mov eax, 1 
    shl eax, cl 
    mov edx, eax 
    add edx, edx 
    or eax, edx 
    ret 
@@err: 
    xor eax, eax 
end; 

Cập nhật:

tôi đã không tìm thấy báo cáo lỗi trong Basm area. Nó trông giống như một lỗi, nhưng tôi đã sử dụng BASM trong nhiều năm và không bao giờ nghĩ đến việc sử dụng từ khóa nhãn như vậy. Trong thực tế, tôi không bao giờ được sử dụng từ khóa nhãn trong Delphi cả. :)

+0

Chà, sửa lỗi đó ... –

+0

Bất kỳ ý tưởng nào tại sao 'nhãn' tạo ra' mov eax, * 'thingy ... Đó có phải là lỗi không? Hoặc chỉ là một số hành vi kỳ lạ? – Egon

+0

Thay vì @@ MyLabel, cũng @ MyLabel (chỉ có một chữ "@") là tốt trong các khối asm..end. – PhiS

1

Vâng ... trở lại sau đó, trong Delphi-Manual, nó được sử dụng để nói điều gì đó về trình biên dịch-Tối ưu hóa và thealike-crazyness:


Các trình biên dịch tạo ra Stackframes chỉ cho thói quen lồng nhau, cho thói quen có biến địa phương và cho thói quen với stack-Tham số

Các tính năng tự động tạo ra Initialization- và Finalizationcode cho thói quen bao gồm:

PUSH EBP    ; If Locals <> 0 or Params <> 0 
MOV  EBP,ESP   ; If Locals <> 0 or Params <> 0 
SUB  ESP,Locals  ; If Locals <> 0 
    ... 
MOV  ESP,EBP   ; If Locals <> 0 
POP  EBP    ; If Locals <> 0 or Params <> 0 
RET  Params   ; Always 

Nếu các biến cục bộ chứa các biến thể, các chuỗi dài hoặc các giao diện chúng được khởi tạo với Null nhưng không được hoàn thành sau đó.

Người dân địa phương là Kích thước của biến cục bộ, Params Kích thước của tham số. Nếu cả hai người dân địa phương cũng như Params là Null không có Init-Code sẽ được tạo ra và Finalizationcode chỉ chứa RET-Intruction.


Có lẽ đã có vài việc phải làm gì với nó tất cả ...

Các vấn đề liên quan