Почему следующая функция c такая же, как код asm - PullRequest
3 голосов
/ 11 декабря 2011

Может кто-нибудь объяснить мне, почему следующий код c эквивалентен коду asm?

void arith1(){
    a=(b*10)+(5/(-e));
}

Почему мы помещаем значение b в регистр ecx.

Код ASM:

mov  ecx, DWORD PTR _b
imul ecx, 10             ; $1 = b * 10
mov  esi, DWORD PTR _e  
neg  esi                 ; $2 = -e
mov  eax, 5
cdq
idiv esi                 ; $3 = 5 / -e
add  ecx, eax            ; $4 = $1 + $3
mov  DWORD PTR _a, ecx   ; a = $4

Ответы [ 2 ]

3 голосов
/ 11 декабря 2011
mov  ecx, DWORD PTR _b
imul ecx, 10             ; edx:eax = b * 10
mov  esi, DWORD PTR _e  
neg  esi                 ; esi = -e
mov  eax, 5
cdq                      ; edx:eax = 5
idiv esi                 ; eax = 5 / -e
add  ecx, eax            ; ecx = b * 10 + 5 / -e
mov  DWORD PTR _a, ecx   ; store result to a

Единственная неинтуитивная часть состоит в том, что инструкции imul и idiv объединяют регистры edx и eax для формирования 64-битного значения.Старшие 32 бита отбрасываются после инструкции imul, C не выполняет проверки переполнения.Инструкция cdq (преобразование double в quad) необходима для преобразования 32-битного значения в 64-битное значение перед делением.

2 голосов
/ 11 декабря 2011
mov  ecx, DWORD PTR _b

Переместить переменную b в регистр ecx

imul     ecx, 10    ; $1 = b * 10

Умножить регистр ecx на 10. (b * 10)

mov  esi, DWORD PTR _e 

Переместить переменную e в esi.регистр.

neg  esi    ; $2 = -e

Отрицать регистр ESI.(-e)

mov  eax, 5

Переместите 5. в регистр eax.

cdq

Преобразуйте eax в четырехзначное слово (думаю, не уверен, для чего он нужен).

idiv     esi    ; $3 = 5 / -e

Разделите eax на esi (5 / -e)

add  ecx, eax   ; $4 = $1 + $3

Добавьте eax к ecx (b * 10) + (5 / -e).

mov  DWORD PTR _a, ecx  ; a = $4

Переместить ecx в переменную a (a = (b * 10) + (5 / -e)).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...